$solution:$
$Trie$树很显然吧,那么如何去处理每次询问。对于$Trie$树的每个节点放一个$vector$表示其若有$v$个人的最小时间。
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<vector> #define ll long long using namespace std; inline int read(){ int f=1,ans=0;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();} return f*ans; } const int MAXN=1000001; vector<int> ve[MAXN]; int ch[MAXN][11],tot,Time[MAXN]; struct Trie{ void insert(char *s,int opt,int k){ int len=strlen(s),u=1; for(int i=0;i<len;i++){ int c=s[i]-'a'; if(!ch[u][c]) ch[u][c]=++tot; u=ch[u][c]; Time[u]+=opt; if(Time[u]>ve[u].size()) ve[u].push_back(k); } } int Query(char *s){ int len=strlen(s),u=1; for(int i=0;i<len;i++){ int c=s[i]-'a'; if(!ch[u][c]) return -1; u=ch[u][c]; }return u; } }trie; int n,ans; char str[61]; int main(){ // freopen("2.in","r",stdin); n=read(); for(int i=1;i<=n;i++){ int opt=read(); if(opt==1){ scanf("%s",str); trie.insert(str,1,i); } if(opt==2){ scanf("%s",str); trie.insert(str,-1,i); } if(opt==3){ scanf("%s",str); int pos=trie.Query(str); ll a=read(),b=read(),c=read(); ans=abs(ans); ll k=(a*ans+b)%c; k=(int)k; /*printf("k:%d\n",k); printf("siz:%d\n",ve[pos][0]);*/ if(pos==-1){ans=-1;printf("%d\n",ans);continue;} if(ve[pos].size()>k){printf("%d\n",ans=ve[pos][k]);continue;} else {ans=-1;printf("%d\n",ans);continue;} } } }