CF1437G Death DBMS

洛谷link
2025/12/13 考试t4
一眼ac自动机,暴力跳fail;
然后发现有名字一样的,同一个节点上有可能叠加很多权值;考试的时候想了个记录的方法过了,结果是考试的数据过水,我的做法实际上是错解;
这个时候就要用multiset来维护一个节点上的权值;

multiset

multiset<int> st[N]
//建立一个二位multiset
//可以将其中的int类型改为自定义的类型,在结构体里写operator定义排序方法(类似优先队列)

st[i].insert(val);
//插入值val

st[i].erase(val);
//把所有值为val的都删掉

auto f = st[i].find(val);//找到值为val的, 没有则返回st[i].end();
if(f != st[i].end()) st[i].erase(f);
//删掉一个值为val的

st[i].begin();
//最小值(会自动从小到大排序)

auto f = st[i].end();
if(!st[i].empty()) f--;
//最大值

st[i].count(val);
//值val出现次数

st[i].clear();
//清空

于是乎在本题中对与每一个节点建一个multiset,对于每一个修改先把上一个这个人的值删除, 再加入当前值, 跳fail时直接在集合中找最大值即可

#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
int n, m, w[N], tr[N][30], g[N], fail[N], vis[N], cnt;
multiset<int> st[N];
char s[N], t[N];
void build(char *s, int b){ //建字典树
	int p = 0;
	for(int i = 0, len = strlen(s); i < len; i++){
		if(!tr[p][s[i] - 'a']) tr[p][s[i] - 'a'] = ++cnt;
		p = tr[p][s[i] - 'a'];
	}
	g[b] = p;
	w[b] = 0;
	st[p].insert(0);
}
void ac(){ //建立fail树
	queue<int> q;
	for(int i = 0; i < 26; i++){
		if(!tr[0][i]) continue;
		fail[tr[0][i]] = 0;
		q.push(tr[0][i]);
	}
	while(!q.empty()){
		int u = q.front();
		q.pop();
		for(int i = 0; i < 26; i++){
			if(tr[u][i]){
				fail[tr[u][i]] = tr[fail[u]][i];
				q.push(tr[u][i]);
			}
			else tr[u][i] = tr[fail[u]][i];
		}
	}
}
int main(){
	cin >> n >> m;
	for(int i = 1; i <= n; i++){
		cin >> s;
		build(s, i);
	}
	ac();
	for(int i = 1; i <= m; i++){
		int mx = -1;
		int opt, x, y;
		cin >> opt;
		if(opt == 1){ //修改操作
			cin >> x >> y;
			st[g[x]].insert(y); //插入当前值
			auto flag = st[g[x]].find(w[x]);
			if(flag != st[g[x]].end()) st[g[x]].erase(flag); //删除上一个值
			w[x] = y; //更新当前值
		}
		else{
			int u = 0, p;
			cin >> t;
			for(int j = 0, len = strlen(t); j < len; j++){
				u = tr[u][t[j] - 'a'];
				p = u;
				while(p){
					if(vis[p] == i) break;
					vis[p] = i;
					auto fg = st[p].end();
					if(!st[p].empty()) {
						fg--; 
						mx = max(mx, *fg);//找到最大值, 更新答案
					} 
					p = fail[p];
				}
			}
			cout << mx << endl;
		}
	}
	return 0;
}
posted @ 2025-12-13 16:44  Turkey_VII  阅读(3)  评论(0)    收藏  举报