社区讨论

70pts 悬关求调 wa on #11-#12 & #17-#20

P14363[CSP-S 2025] 谐音替换参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mhpi1gzr
此快照首次捕获于
2025/11/08 07:41
3 个月前
此快照最后确认于
2025/11/08 07:41
3 个月前
查看原帖
如题。做法为 hash+trie+二维数点。
CPP
#include <bits/stdc++.h>
#define p 998244353
#define K 131
using namespace std;

inline long long read(void) {
	long long x = 0, f = 1; char c = getchar();
	while (c > '9' || c < '0') {
		if (c == '-') f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + c - 48, c = getchar();
	return x * f;
}

inline void getstr (string &x) {
	x. clear();
	char c = getchar();
	while (c > 'z' || c < 'a') c = getchar();
	while (c >= 'a' && c <= 'z') x. push_back(c), c = getchar();
}

struct node {
	int x, y, id;
	friend bool operator< (node x, node y) {
		return x. x == y. x ? (x. y == y. y ? x. id < y. id : x. y < y. y) : x. x < y. x;
	}
};

vector<node> solve;

long long n, q, pw[5000005];
int nt[6000005][26], nt2[6000005][26], c[6000005], T, cnt, cnt2, cnt3, cnt4, fstq[200005], lstq[200005], fst[200005], lst[200005], dfn[6000005], dfn2[6000005], g[6000005], g2[6000005], sum[6000005], sum2[6000005], ans[200005];
map<pair<long long, long long>, long long> rt, rt2, updid, qryid;
vector<pair<int, int> > upd[2000005];
vector<int> query[2000005];
vector<int> nxt[6000005], nxt2[6000005];
string a[200005], b[200005], _ns[200005], _nt[200005];

void init (int x) {
	dfn[x] = ++T, g[x] = 1;
	for (auto i : nxt[x]) init(i), g[x] += g[i];
}

void init2 (int x) {
	dfn2[x] = ++T, g2[x] = 1;
	for (auto i : nxt2[x]) init2(i), g2[x] += g2[i];
}

void upd2 (int x, int y) {
	if (x > T) return;
	c[x] += y;
	upd2(x + (x & -x), y);
}

int query2 (int x) {
	if (!x) return 0;
	return c[x] + query2(x - (x & -x));
}

int main(void) {
	n = read(), q = read();
	pw[0] = 1;
	for (int i = 1; i <= 5000000; i++) pw[i] = pw[i - 1] * K % p;
	for (int i = 1; i <= n; i++) {
		getstr(a[i]), getstr(b[i]);
		int len = a[i]. size();
		fst[i] = -1, lst[i] = -1;
		long long sm = 0, sm2 = 0;
		for (int j = 0; j < len; j++) {
			if (a[i][j] == b[i][j]) continue;
			if (fst[i] == -1) fst[i] = j;
			lst[i] = j;
			(sm += a[i][j] * pw[j - fst[i]] % p) %= p;
			(sm2 += b[i][j] * pw[j - fst[i]] % p) %= p;
		}
		if (fst[i] == -1) continue;
		if (!rt[{sm, sm2}]) rt[{sm, sm2}] = ++cnt;
		if (!rt2[{sm, sm2}]) rt2[{sm, sm2}] = ++cnt2;
		long long w = rt[{sm, sm2}];
		for (int j = fst[i] - 1; j >= 0; j--) {
			if (!nt[w][a[i][j] - 'a']) nt[w][a[i][j] - 'a'] = ++cnt, nxt[w]. push_back(cnt);
			w = nt[w][a[i][j] - 'a'];
		}
		long long w2 = rt2[{sm, sm2}];
		for (int j = lst[i] + 1; j < len; j++) {
			if (!nt2[w2][a[i][j] - 'a']) nt2[w2][a[i][j] - 'a'] = ++cnt2, nxt2[w2]. push_back(cnt2);
			w2 = nt2[w2][a[i][j] - 'a'];
		}
		if (!updid[{sm, sm2}]) updid[{sm, sm2}] = ++cnt4;
		upd[updid[{sm, sm2}]]. push_back({w, w2});
	}
	for (int i = 1; i <= q; i++) {
		getstr(_ns[i]), getstr(_nt[i]);
		int len = _ns[i]. size();
		fstq[i] = lstq[i] = -1;
		long long sm = 0, sm2 = 0;
		for (int j = 0; j < len; j++) {
			if (_ns[i][j] == _nt[i][j]) continue;
			if (fstq[i] == -1) fstq[i] = j;
			lstq[i] = j;
			(sm += pw[j - fstq[i]] * _ns[i][j] % p) %= p;
			(sm2 += pw[j - fstq[i]] * _nt[i][j] % p) %= p;
		}
		if (rt[{sm, sm2}]) {
			if (!qryid[{sm, sm2}]) qryid[{sm, sm2}] = ++cnt3;
			query[qryid[{sm, sm2}]]. push_back(i);
		}
	}
	for (auto _i : rt) {
		long long i = _i. second, j = rt2[_i. first], k = qryid[_i. first], u = updid[_i. first];
		if (!k) continue;
		T = 0;
		init(i);
		T = 0;
		init2(j);
		solve. clear();
		for (auto _xx : upd[u]) {
			int xx = _xx. first, yy = _xx. second;
			solve. push_back({dfn[xx], dfn2[yy], 0});
			solve. push_back({dfn[xx] + g[xx], dfn2[yy], -2});
			solve. push_back({dfn[xx], dfn2[yy] + g2[yy], -2});
			solve. push_back({dfn[xx] + g[xx], dfn2[yy] + g2[yy], 0});
		}
		for (auto xx : query[k]) {
			long long w = i;
			for (int _ = fstq[xx] - 1; _ >= 0; _--) {
				if (!nt[w][_ns[xx][_] - 'a']) break;
				w = nt[w][_ns[xx][_] - 'a'];
			}
			long long w2 = j;
			for (int _ = lstq[xx] + 1; _ < _ns[xx]. size(); _++) {
				if (!nt2[w2][_ns[xx][_] - 'a']) break;
				w2 = nt2[w2][_ns[xx][_] - 'a'];
			}
			solve. push_back({dfn[w], dfn2[w2], xx});
		}
		sort(solve. begin(), solve. end());
		for (auto mygo : solve) {
			if (mygo. id > 0) ans[mygo. id] = query2(mygo. y);
			else upd2(mygo. y, mygo. id + 1);
		}
		for (auto mygo : solve) if (mygo. id <= 0) upd2(mygo. y, -mygo. id - 1);
	}
	for (int i = 1; i <= q; i++) printf("%d\n", ans[i]);
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...