A dictionary example of the tree, right
1, said first two conditions before the ideas are easily satisfied, to modify trie insert, the third condition can be used to implement a dynamic array, able to save its size indicates that the current node has several passes (i.e. number), which subscript represents a handful of appearances, which is stored in the number of operations (ie time), you can then modify the dictionary tree.
The Code
#include<bits/stdc++.h>
using namespace std;
const int N=300000;//开大点200000有一个点没过
struct node{
int ch[30],size;
vector<int> cmp;//动态数组
}trie[N];
int n,k,tot,a,b,c,ans;
char str[100];
struct tr{
void ins(char a[],int num){//插入
int len=strlen(a);
int p=0;
for(int i=0;i<len;++i){
int v=a[i]-'a';
if(!trie[p].ch[v]) trie[p].ch[v]=++tot;
p=trie[p].ch[v];
trie[p].size++;
if(trie[p].size>trie[p].cmp.size())trie[p].cmp.push_back(num);
}
}
void deal(char a[]){//删除
int p=0,len=strlen(a);
for(int i=0;i<len;++i){
int v=a[i]-'a';
p=trie[p].ch[v];
trie[p].size--;
}
}
int found(char s[],long long a,long long b,long long c){//找答案
int p=0,len=strlen(s);
long long tmp=(a*abs(ans)+b)%c;
for(int i=0;i<len;++i){
int v=s[i]-'a';
p=trie[p].ch[v];
if(trie[p].cmp.size()<=tmp) return -1;//没超过
}
return trie[p].cmp[tmp];
}
}tr;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&k);
if(k==1){
scanf("%s",str);
tr.ins(str,i);
}
if(k==2){
scanf("%s",str);
tr.deal(str);
}
if(k==3){
scanf("%s",str);
scanf("%d %d %d",&a,&b,&c);
printf("%d\n",ans=tr.found(str,a,b,c));//记得修改答案
}
}
return 0;
}