题目链接http://codeforces.com/gym/102448/problem/C
题意
三种操作,一共有个:
- :在字典里插入字符串
- :在字典里删除字符串
- :输出字典中最短的且前缀是 的下标。如果有多个字符串,输出字典序最小的。
字符串的下标是指该串被插入时的时间。
输入中所有的字符串长度和不超过
题解
第一眼感觉是可持久化AC自动机?不会啊。然后就看到了这个条件:所有的字符串长度和不超过 ,决定乱搞。
对每个长度开一个,表示存在一个 的字符串满足长度为 的前缀哈希值是 。
里记录一下字符串的信息,比如长度啊,字典序啊,下标啊。这个字典序我的求法就比较夸张,直接全部读进来,离散排个序。
然后三种操作只要对应的把 和 维护好就行了。
这绝对不是标准做法 但是我过了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+7;
int q;
int op[N];
string s[N],ss[N];
int px[N];
int er[N];
struct Node{
int id,len,p;
bool operator<(const Node k)const{
if(len==k.len) return p<k.p;
return len<k.len;
}
};
unordered_map<unsigned long long,set<Node>>mp[N*10];
int main(){
scanf("%d",&q);
for(int i=1;i<=q;i++){
scanf("%d",&op[i]);
if(op[i]==2) scanf("%d",&er[i]),ss[i]=ss[er[i]];
else cin>>ss[i];
s[i]=ss[i];
}
sort(ss+1,ss+1+q);
for(int i=1;i<=q;i++){
px[i]=lower_bound(ss+1,ss+1+q,s[i])-ss;
}
for(int i=1;i<=q;i++){
if(op[i]==1){
unsigned long long h=0;
for(int j=0;j<s[i].length();j++){
h=h*233+s[i][j]-'a';
mp[j][h].insert((Node){i,s[i].length(),px[i]});
}
}
else if(op[i]==2){
unsigned long long h=0;
h=0;
for(int j=0;j<s[i].length();j++){
h=h*233+s[i][j]-'a';
mp[j][h].erase((Node){er[i],s[i].length(),px[i]});
}
}
else{
unsigned long long h=0;
for(int j=0;j<s[i].length();j++){
h=h*233+s[i][j]-'a';
}
if(mp[s[i].length()-1][h].empty()) printf("-1\n");
else printf("%d\n",(*mp[s[i].length()-1][h].begin()).id);
}
}
}
来源:CSDN
作者:Elliott__
链接:https://blog.csdn.net/monochrome00/article/details/104172928