【哈希】Gym - 102448 - C - Call from Mendes

强颜欢笑 提交于 2020-02-05 00:04:33

题目链接http://codeforces.com/gym/102448/problem/C


题意

三种操作,一共有QQ个:

  • 1  X1\;X:在字典里插入字符串 XX
  • 2  X2\;X:在字典里删除字符串 XX
  • 3  X3\; X:输出字典中最短的且前缀是 XX 的下标。如果有多个字符串,输出字典序最小的。

字符串的下标是指该串被插入时的时间。

输入中所有的字符串长度和不超过10610^6


题解

第一眼感觉是可持久化AC自动机?不会啊。然后就看到了这个条件:所有的字符串长度和不超过 10610^6 ,决定乱搞。

对每个长度开一个map<hash,set>[i]map<hash, set>[i],表示存在一个 setset 的字符串满足长度为 ii 的前缀哈希值是 hashhash

setset 里记录一下字符串的信息,比如长度啊,字典序啊,下标啊。这个字典序我的求法就比较夸张,直接全部读进来,离散排个序。

然后三种操作只要对应的把 mapmapsetset 维护好就行了。

这绝对不是标准做法 但是我过了


#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);
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!