QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#257112 | #7748. Karshilov's Matching Problem II | ucup-team296# | WA | 212ms | 156032kb | C++20 | 9.4kb | 2023-11-19 00:17:09 | 2023-11-19 00:17:09 |
Judging History
answer
#include <bits/stdc++.h>
/**
* Author: Niyaz Nigmatullin
*
*/
using namespace std;
string to_string(string s) {
return '"' + s + '"';
}
string to_string(const char* s) {
return to_string((string) s);
}
string to_string(bool b) {
return (b ? "true" : "false");
}
template <typename A, typename B>
string to_string(pair<A, B> p) {
return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
template <typename A>
string to_string(A v) {
bool first = true;
string res = "{";
for (const auto &x : v) {
if (!first) {
res += ", ";
}
first = false;
res += to_string(x);
}
res += "}";
return res;
}
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
cerr << " " << to_string(H);
debug_out(T...);
}
#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif
struct upinfo {
int left;
int right;
int index = -1;
};
struct node {
long long sum = 0;
upinfo updateInfo;
static node single(long long x) {
node res;
res.sum = x;
return res;
}
void apply(int l, int r, upinfo info);
void apply(int l, int r, int x) {
*this = single(x);
}
};
node unite(const node &a, const node &b) {
node res;
res.sum = a.sum + b.sum;
return res;
}
struct update {
static const int K = 20;
vector<long long> values;
int n;
vector<vector<node>> tt;
update(vector<long long> values_): values(std::move(values_)), n((int) values.size()), tt(K, vector<node>(n)) {
for (int i = 0; i < n; i++) {
tt[0][i] = node::single(values[i]);
}
for (int i = 1; i < K; i++) {
for (int v = 0; v < n; v++) {
tt[i][v] = unite(tt[i - 1][v], tt[i - 1][(v + (1 << (i - 1))) % n]);
}
}
}
node get(int start, int len) {
node res;
start %= n;
for (int i = K - 1; i >= 0; i--) {
if (len >= (1 << i)) {
len -= 1 << i;
// debug(i, start, n, tt[i][start]);
res = unite(res, tt[i][start]);
start = (start + (1 << i)) % n;
}
}
return res;
}
};
vector<update> updates;
string to_string(node const &s) {
return "node{sum=" + to_string(s.sum) + "}";
}
void node::apply(int l, int r, upinfo info) {
assert(info.left <= l && r <= info.right);
int start = l - info.left;
node res = updates[info.index].get(start, r - l + 1);
res.updateInfo = info;
*this = res;
}
class segtree {
public:
inline void push(int x, int l, int r) {
if (tree[x].updateInfo.index < 0) {
return;
}
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
// push from x into (x + 1) and z
tree[x + 1].apply(l, y, tree[x].updateInfo);
tree[z].apply(y + 1, r, tree[x].updateInfo);
/*
if (tree[x].add != 0) {
tree[x + 1].apply(l, y, tree[x].add);
tree[z].apply(y + 1, r, tree[x].add);
tree[x].add = 0;
}
*/
}
inline void pull(int x, int z) {
tree[x] = unite(tree[x + 1], tree[z]);
}
int n;
vector<node> tree;
void build(int x, int l, int r) {
if (l == r) {
return;
}
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
build(x + 1, l, y);
build(z, y + 1, r);
pull(x, z);
}
template <typename M>
void build(int x, int l, int r, const vector<M> &v) {
if (l == r) {
tree[x].apply(l, r, v[l]);
return;
}
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
build(x + 1, l, y, v);
build(z, y + 1, r, v);
pull(x, z);
}
node get(int x, int l, int r, int ll, int rr) {
if (ll <= l && r <= rr) {
return tree[x];
}
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
push(x, l, r);
node res{};
if (rr <= y) {
res = get(x + 1, l, y, ll, rr);
} else {
if (ll > y) {
res = get(z, y + 1, r, ll, rr);
} else {
res = unite(get(x + 1, l, y, ll, rr), get(z, y + 1, r, ll, rr));
}
}
pull(x, z);
return res;
}
template <typename... M>
void modify(int x, int l, int r, int ll, int rr, const M&... v) {
if (ll <= l && r <= rr) {
tree[x].apply(l, r, v...);
return;
}
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
push(x, l, r);
if (ll <= y) {
modify(x + 1, l, y, ll, rr, v...);
}
if (rr > y) {
modify(z, y + 1, r, ll, rr, v...);
}
pull(x, z);
}
int find_first_knowingly(int x, int l, int r, const function<bool(const node&)> &f) {
if (l == r) {
return l;
}
push(x, l, r);
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
int res;
if (f(tree[x + 1])) {
res = find_first_knowingly(x + 1, l, y, f);
} else {
res = find_first_knowingly(z, y + 1, r, f);
}
pull(x, z);
return res;
}
int find_first(int x, int l, int r, int ll, int rr, const function<bool(const node&)> &f) {
if (ll <= l && r <= rr) {
if (!f(tree[x])) {
return -1;
}
return find_first_knowingly(x, l, r, f);
}
push(x, l, r);
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
int res = -1;
if (ll <= y) {
res = find_first(x + 1, l, y, ll, rr, f);
}
if (rr > y && res == -1) {
res = find_first(z, y + 1, r, ll, rr, f);
}
pull(x, z);
return res;
}
int find_last_knowingly(int x, int l, int r, const function<bool(const node&)> &f) {
if (l == r) {
return l;
}
push(x, l, r);
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
int res;
if (f(tree[z])) {
res = find_last_knowingly(z, y + 1, r, f);
} else {
res = find_last_knowingly(x + 1, l, y, f);
}
pull(x, z);
return res;
}
int find_last(int x, int l, int r, int ll, int rr, const function<bool(const node&)> &f) {
if (ll <= l && r <= rr) {
if (!f(tree[x])) {
return -1;
}
return find_last_knowingly(x, l, r, f);
}
push(x, l, r);
int y = (l + r) >> 1;
int z = x + ((y - l + 1) << 1);
int res = -1;
if (rr > y) {
res = find_last(z, y + 1, r, ll, rr, f);
}
if (ll <= y && res == -1) {
res = find_last(x + 1, l, y, ll, rr, f);
}
pull(x, z);
return res;
}
segtree(int _n) : n(_n) {
assert(n > 0);
tree.resize(2 * n - 1);
build(0, 0, n - 1);
}
template <typename M>
segtree(const vector<M> &v) {
n = (int) v.size();
assert(n > 0);
tree.resize(2 * n - 1);
build(0, 0, n - 1, v);
}
node get(int ll, int rr) {
assert(0 <= ll && ll <= rr && rr <= n - 1);
return get(0, 0, n - 1, ll, rr);
}
node get(int p) {
assert(0 <= p && p <= n - 1);
return get(0, 0, n - 1, p, p);
}
template <typename... M>
void modify(int ll, int rr, const M&... v) {
assert(0 <= ll && ll <= rr && rr <= n - 1);
modify(0, 0, n - 1, ll, rr, v...);
}
// find_first and find_last call all FALSE elements
// to the left (right) of the sought position exactly once
int find_first(int ll, int rr, const function<bool(const node&)> &f) {
assert(0 <= ll && ll <= rr && rr <= n - 1);
return find_first(0, 0, n - 1, ll, rr, f);
}
int find_last(int ll, int rr, const function<bool(const node&)> &f) {
assert(0 <= ll && ll <= rr && rr <= n - 1);
return find_last(0, 0, n - 1, ll, rr, f);
}
};
vector<int> zFunction(string const &s) {
int n = (int) s.size();
vector<int> z(n);
int left = 0;
int right = 0;
for (int i = 1; i < n; i++) {
z[i] = i >= right ? 0 : min(right - i, z[i - left]);
while (i + z[i] < n && s[z[i]] == s[i + z[i]]) {
++z[i];
}
if (i + z[i] > right) {
left = i;
right = i + z[i];
}
}
return z;
}
vector<long long> getV(string const &s, vector<int> const &w) {
int n = (int) s.size();
vector<int> p(n);
vector<long long> sum(n);
int k = -1;
p[0] = -1;
sum[0] = w[0];
for (int i = 1; i < n; i++) {
while (k > -1 && s[k + 1] != s[i]) {
k = p[k];
}
if (s[k + 1] == s[i]) {
k++;
}
sum[i] = w[i];
if (k >= 0) {
sum[i] += sum[k];
}
}
return sum;
}
struct stupidtree {
vector<long long> s;
stupidtree(int n) : s(n) {}
void modify(int left, int right, upinfo info) {
for (int i = left; i <= right; i++) {
s[i] = updates[info.index].values[i - left];
}
}
node get(int left, int right) {
long long ans = 0;
for (int i = left; i <= right; i++) {
ans += s[i];
}
node res;
res.sum = ans;
return res;
}
};
vector<long long> solveSmart(string const &s, string const &t, vector<int> const &w, vector<pair<int, int>> const &qs) {
int n = (int) w.size();
string zs = s + "@" + t;
vector<int> z = zFunction(zs);
int lenT = (int) t.size();
vector<vector<int>> qByL(lenT);
int queries = (int) qs.size();
for (int i = 0; i < queries; i++) {
qByL[qs[i].first].push_back(i);
}
updates = {update(getV(s, w))};
segtree tree(vector<int>(lenT, 0));
// stupidtree tree(lenT);
vector<long long> ans(queries);
for (int i = lenT - 1; i >= 0; i--) {
int maxLen = z[n + 1 + i];
if (maxLen > 0) {
tree.modify(i, i + maxLen - 1, upinfo{i, i + maxLen - 1, 0});
}
for (int qid : qByL[i]) {
int right = qs[qid].second;
ans[qid] = tree.get(i, right).sum;
}
}
return ans;
}
int main() {
std::cin.tie(NULL); std::ios::sync_with_stdio(false);
int n, m;
cin >> n >> m;
string s, t;
cin >> s >> t;
vector<int> w(n);
for (int &x: w) cin >> x;
vector<pair<int, int>> qs(m);
for (auto &e: qs) {
cin >> e.first >> e.second;
e.first--;
e.second--;
}
vector<long long> ans = solveSmart(s, t, w, qs);
for (auto &x : ans) {
cout << x << '\n';
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3656kb
input:
8 5 abbabaab aababbab 1 2 4 8 16 32 64 128 1 1 2 3 3 5 4 7 1 8
output:
1 3 3 16 38
result:
ok 5 lines
Test #2:
score: 0
Accepted
time: 0ms
memory: 3668kb
input:
15 4 heheheheehhejie heheheheheheheh 3 1 4 1 5 9 2 6 5 3 5 8 9 7 9 2 3 4 8 2 6 1 15
output:
3 13 13 174
result:
ok 4 lines
Test #3:
score: 0
Accepted
time: 187ms
memory: 156032kb
input:
150000 150000 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
output:
108147037823514 221878585246974 455339807727642 440286198422821 148115747906237 88695249853257 351159618462315 58850354020997 65824434822005 270158033672354 197732558443069 298193894693053 239511187032650 28139154231325 408380171835227 268053430937402 32417121185965 104813548228675 44074926058619 78...
result:
ok 150000 lines
Test #4:
score: -100
Wrong Answer
time: 212ms
memory: 155888kb
input:
150000 150000 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...
output:
503969317928829 112638556022185 503915587474294 2166223193286432 295388515578381 1618048602896769 632231520585472 166322478628783 485038046183630 1166225262583093 1443449684311962 477676900398846 55994169916421 540623785795639 2472139575834189 2294192983107523 2826063325778731 154700081279584 148483...
result:
wrong answer 1st lines differ - expected: '528900815691571', found: '503969317928829'