21.11.12模拟 P5335 [THUSC2016]补退选

题目要求查询以字符串S为前缀(显然是Trie树)的个数大于k的最早时刻,可以在Trie每个节点开个vector记录达到k的最早时刻,删除的时候不动vector即可

const int N = 1e5 + 79;
//trie +vector
char s[107];
int lastans;
struct Trie {
	int tot;
	int ch[N * 40][11];
	int siz[N * 40];
	std::vector<int> ans[N * 40];
	inline void insert(char *s, int tim) {
		int p(0);
		for(int i(0); s[i]; ++i) {
			int x = s[i] - 'a';
			if(!ch[p][x]) ch[p][x] = ++tot;
			p = ch[p][x];

			if(++siz[p] > ans[p].size()) {
				ans[p].push_back(tim);
			}
		}
	}
	inline void del(char *s) {
		int p(0);
		for(int i(0); s[i]; ++i) {
			int x = s[i] - 'a' ;
			p = ch[p][x];
			--siz[p];
		}
	}
	inline int query(char *s, int a, int b, int c) {
		lxl num = 1ll * (1ll * a * abs(lastans) + b) % c;
		int p(0);
		for(int i(0); s[i]; ++i) {
			int x = s[i] - 'a' ;
			p = ch[p][x];
			if(ans[p].size() <= num) return -1;
		}
		return ans[p][num];
	}
} T;
int main() {
	freopen("selection.in", "r", stdin);
	freopen("selection.out", "w", stdout);
	std::ios::sync_with_stdio(false);
	int n;
	cin >> n;
	int op, b, c, a;
	rep(i, 1, n) {
		cin >> op >> s;
		if(op == 1) {
			T.insert(s, i);
		} else if(op == 2) {
			T.del(s);
		} else {
			cin >> a >> b >> c;
			cout << (lastans = T.query(s, a, b, c)) << '
';
		}
	}
	return 0;
}

本文来自博客园,作者:{2519},转载请注明原文链接:https://www.cnblogs.com/QQ2519/p/15547305.html

原文地址:https://www.cnblogs.com/QQ2519/p/15547305.html