QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#625650#9425. Generated Stringskip2004WA 16ms31232kbC++204.2kb2024-10-09 20:13:092024-10-09 20:13:10

Judging History

你现在查看的是最新测评结果

  • [2024-10-14 17:49:05]
  • hack成功,自动添加数据
  • (/hack/995)
  • [2024-10-09 20:13:10]
  • 评测
  • 测评结果:WA
  • 用时:16ms
  • 内存:31232kb
  • [2024-10-09 20:13:09]
  • 提交

answer

#include<bits/stdc++.h>
namespace rgs = std::ranges;
using std::cin, std::cout;
using ll = long long;
using u64 = unsigned long long;
using db = double;
using pr = std::pair<int, int>;
const int N = 200005;
int n, q;
char s[N];
char op[N];
int id[N];
int r[2][N], rk[2][N];
std::vector<pr> str[N], str2[N];

namespace SA {
	int rank[N], sa[N], h[N], n, L;
	int st[20][N];
	bool cmp(int a, int b) {
		if(rank[a] != rank[b]) return rank[a] < rank[b];
		return b + L <= n && (a + L > n || rank[a + L] < rank[b + L]);
	}
	int lcp(int x, int y) {
		if(x == y) return n - x + 1;
		x = rank[x], y = rank[y];
		if(x > y) std::swap(x, y);
		const int lg = std::__lg(y - x);
		return std::min(st[lg][x], st[lg][y - (1 << lg)]);
	}
	void SA() {
		static int a[N], t[N];
		for(int i = 1;i <= n;++i) rank[i] = s[i];
		std::iota(a, a + n + 1, 0);
		for(L = 1;;L <<= 1) {
			std::sort(a + 1, a + n + 1, cmp);
			for(int i = 1, r = 0;i <= n;++i) {
				t[a[i]] = r += !i || cmp(a[i - 1], a[i]);
			}
			memcpy(rank + 1, t + 1, n << 2);
			if(t[a[n]] == n) break;
		}
		for(int i = 1;i <= n;++i) sa[rank[i]] = i;
		for(int i = 1, k = 0;i <= n;++i) if(rank[i] < n) {
			int j = sa[rank[i] + 1];
			for(k -= !!k;s[i + k] == s[j + k];++k);
			h[rank[i]] = k;
			st[0][rank[i]] = k;
		}
		for(int i = 1;i < 20;++i) {
			for(int j = 1;j + (1 << i) - 1 < n;++j) {
				st[i][j] = std::min(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
			}
		}

	}
	using str_t = std::vector<pr>;
	using op_t = std::pair<str_t, int>;
	int comp(int a, int b) {
		return a < b ? -1 : a > b;
	}

	void solve(int * r, int * rk) {
		n = ::n + 1, s[n] = 127;
		SA();
		auto cmp = [&](str_t x, str_t y) {
			int i = 0, j = 0;
			for(;i < (int) x.size() && j < (int) y.size();) {
				auto & [l0, r0] = x[i];
				auto & [l1, r1] = y[j];
				int z = std::min({lcp(l0, l1), r0 - l0 + 1, r1 - l1 + 1});
				l0 += z, l1 += z;
				if(l0 <= r0 && l1 <= r1) {
					return comp(s[l0], s[l1]);
				} else {
					if(l0 > r0) ++ i;
					if(l1 > r1) ++ j;
				}
			}
			return comp(i != (int) x.size(), j != (int) y.size());
		};
		std::vector<op_t> v;
		for(int i = 1;i <= q;++i) {
			if(op[i] == '+' || op[i] == '?') {
				v.emplace_back(str[i], i);
				if(op[i] == '?') {
					auto tmp = str[i];
					tmp.emplace_back(n, n);
					v.emplace_back(tmp, -i);
				}
			}
		}
		std::mt19937 gen(1241241);
		shuffle(v.begin(), v.end(), gen);
		stable_sort(v.begin(), v.end(), [&](const auto & x, const auto & y) {
			int res = cmp(x.first, y.first);
			if(res == 0) {
				return x.second > y.second;
			} else {
				return res == -1;
			}
		});
		int p = 0;
		for(auto [s, id] : v) {
			if(id < 0) {
				r[-id] = p;
			} else {
				rk[id] = ++p;
			}
		}
	}
}

#include<bits/extc++.h>
using namespace __gnu_pbds;
tree<int, null_type, std::less<int>, rb_tree_tag, tree_order_statistics_node_update> bit[N];

void add(int x, int v, int op) {
	for(;x <= n;x += x & -x) {
		if(op) {
			bit[x].insert(v);
		} else {
			bit[x].erase(v);
		}
	}
}
int query(int x, int l, int r) {
	int ans = 0;
	for(;x;x &= x - 1) {
		ans += bit[x].order_of_key(r + 1) - bit[x].order_of_key(l);
	}
	return ans;
}

int main() {
	std::ios::sync_with_stdio(false), cin.tie(0);
	cin >> n >> q;
	for(int i = 1;i <= n;++i) {
		cin >> s[i];
	}
	for(int i = 1;i <= q;++i) {
		cin >> op[i];
		if(op[i] == '+' || op[i] == '?') {
			int k; cin >> k;
			for(int j = 0, l, r;j < k;++j) {
				cin >> l >> r;
				str[i].emplace_back(l, r);
			}
			if(op[i] == '?') {
				int k; cin >> k;
				for(int j = 0, l, r;j < k;++j) {
					cin >> l >> r;
					str2[i].emplace_back(l, r);
				}
			}
		} else {
			cin >> id[i];
		}
	}
	SA::solve(r[0], rk[0]);
	std::reverse(s + 1, s + n + 1);
	for(int i = 1;i <= q;++i) {
		if(op[i] == '?') str[i] = str2[i];
		reverse(str[i].begin(), str[i].end());
		for(auto & [x, y] : str[i]) {
			std::swap(x = n + 1 - x, y = n + 1 - y);
		}
	}
	SA::solve(r[1], rk[1]);
	for(int i = 1;i <= q;++i) {
		if(op[i] == '+') {
			add(rk[0][i], rk[1][i], 1);
		} else if(op[i] == '-') {
			add(rk[0][id[i]], rk[1][id[i]], 0);
		} else {
			int ans = query(r[0][i], rk[1][i], r[1][i]) - query(rk[0][i] - 1, rk[1][i], r[1][i]);
			cout << ans << '\n';
		}
	}
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 8ms
memory: 31232kb

input:

8 7
abcaabbc
+ 3 1 3 2 4 3 8
+ 2 1 4 1 8
+ 1 2 4
? 1 5 6 1 7 8
- 3
+ 1 2 5
? 1 2 3 1 5 5

output:

2
1

result:

ok 2 lines

Test #2:

score: -100
Wrong Answer
time: 16ms
memory: 29780kb

input:

5 2000
bbaab
+ 1 3 5
+ 2 5 5 3 5
- 2
? 1 1 3 3 3 3 4 5 2 5
- 1
? 3 1 1 2 4 1 5 1 3 4
? 1 1 2 2 2 4 4 4
? 1 1 5 1 5 5
+ 3 1 2 1 5 1 4
? 2 1 5 1 3 2 1 2 5 5
? 1 3 4 1 4 5
- 9
? 1 1 4 1 2 3
+ 2 1 5 1 2
+ 1 1 4
- 15
- 14
? 2 2 5 2 5 1 3 4
+ 1 2 3
- 19
+ 3 1 4 1 5 4 5
- 21
+ 1 2 5
? 3 1 5 5 5 1 5 1 3 5
?...

output:

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
...

result:

wrong answer 10th lines differ - expected: '1', found: '0'