bzoj4943 [Noi2017]蚯蚓排队

题面:http://www.lydsy.com/JudgeOnline/upload/Noi2017D1.pdf

 

正解:字符串$hash$。

我在考场上写了个$map$的$hash$被卡成$40$分,然后改成挂链版本的就$AC$了。。$mdzz$,以后$hash$再也不写$map$了。。

我们考虑使用链表来表示字符间的关系,合并和分裂都用链表来表示,这样我们可以快速找到两个字符的前$k$个和后$k$个字符。

注意到每次只会增加或减少$k^{2}$个字符串,那么我们直接把这些字符串$hash$起来即可,查询统计也很简单。

这道题好像是被骂得最惨的一道题??有人说出题人想告诉我们$SAM$,后缀数组这些高级字符串数据结构都没用。。

 

  1 //It is made by wfj_2048~
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <cstring>
  5 #include <cstdlib>
  6 #include <cstdio>
  7 #include <vector>
  8 #include <cmath>
  9 #include <queue>
 10 #include <stack>
 11 #include <map>
 12 #include <set>
 13 #define rhl (998244353)
 14 #define wyh (19260817)
 15 #define M (10000010)
 16 #define N (300010)
 17 #define il inline
 18 #define RG register
 19 #define ll long long
 20 #define ull unsigned long long
 21 
 22 using namespace std;
 23 
 24 struct edge{ int nt,sum; ull v; }g[12000010];
 25 
 26 int head[wyh+10],a[N],lst[N],nxt[N],st1[60],st2[60],tong[10],n,m,num,fg,top1,top2;
 27 ull hsh[M],bin[M],base=7;
 28 char s[M];
 29 ll ans;
 30 
 31 il int gi(){
 32     RG int x=0,q=1; RG char ch=getchar();
 33     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
 34     if (ch=='-') q=-1,ch=getchar();
 35     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
 36     return q*x;
 37 }
 38 
 39 il void insert(RG int from,RG ull to){
 40     g[++num]=(edge){head[from],1,to},head[from]=num; return;
 41 }
 42 
 43 il void add(RG ull Hash){
 44     RG int ymd=Hash%wyh;
 45     for (RG int i=head[ymd];i;i=g[i].nt)
 46     if (g[i].v==Hash){ ++g[i].sum; return; }
 47     return insert(ymd,Hash);
 48 }
 49 
 50 il void del(RG ull Hash){
 51     RG int ymd=Hash%wyh;
 52     for (RG int i=head[ymd];i;i=g[i].nt)
 53     if (g[i].v==Hash){ --g[i].sum; return; }
 54     return;
 55 }
 56 
 57 il ll calc(RG ull Hash){
 58     RG int ymd=Hash%wyh;
 59     for (RG int i=head[ymd];i;i=g[i].nt)
 60     if (g[i].v==Hash) return g[i].sum;
 61     return 0;
 62 }
 63 
 64 int main(){
 65 #ifndef ONLINE_JUDGE
 66     freopen("queue.in","r",stdin);
 67     freopen("queue.out","w",stdout);
 68 #endif
 69     n=gi(),m=gi(),fg=1,bin[0]=1;
 70     for (RG int i=1;i<=10000000;++i) bin[i]=bin[i-1]*base;
 71     for (RG int i=1;i<=n;++i){ a[i]=gi(),++tong[a[i]]; if (a[i]!=1) fg=0; }
 72     for (RG int i=1;i<=n;++i) lst[i]=nxt[i]=i;
 73     for (RG int p=1,op,x,y,k,len;p<=m;++p){
 74     op=gi();
 75     if (op==1){
 76         x=gi(),y=gi(),top1=top2=0,st1[++top1]=x,st2[++top2]=y;
 77         for (RG int i=x;top1<49 && lst[i]!=i;i=lst[i]) st1[++top1]=lst[i];
 78         for (RG int i=y;top2<49 && nxt[i]!=i;i=nxt[i]) st2[++top2]=nxt[i];
 79         RG ull Hsh=0; for (RG int i=top1;i;--i) Hsh=Hsh*base+a[st1[i]]; st1[top1+1]=0;
 80         for (RG int i=top1;i;--i){
 81         RG ull Hash=Hsh-a[st1[i+1]]*bin[i]; Hsh=Hash,len=i;
 82         for (RG int j=1;j<=top2;++j){
 83             ++len; if (len>50) break;
 84             Hash=Hash*base+a[st2[j]],add(Hash);
 85         }
 86         }
 87         nxt[x]=y,lst[y]=x;
 88     }
 89     if (op==2){
 90         x=gi(),y=nxt[x],top1=top2=0,st1[++top1]=x,st2[++top2]=y;
 91         for (RG int i=x;top1<49 && lst[i]!=i;i=lst[i]) st1[++top1]=lst[i];
 92         for (RG int i=y;top2<49 && nxt[i]!=i;i=nxt[i]) st2[++top2]=nxt[i];
 93         RG ull Hsh=0; for (RG int i=top1;i;--i) Hsh=Hsh*base+a[st1[i]]; st1[top1+1]=0;
 94         for (RG int i=top1;i;--i){
 95         RG ull Hash=Hsh-a[st1[i+1]]*bin[i]; Hsh=Hash,len=i;
 96         for (RG int j=1;j<=top2;++j){
 97             ++len; if (len>50) break;
 98             Hash=Hash*base+a[st2[j]],del(Hash);
 99         }
100         }
101         nxt[x]=x,lst[y]=y;
102     }
103     if (op==3){
104         scanf("%s",s+1),k=gi(),len=strlen(s+1),ans=1; RG ull Hash;
105         if (k==1){
106         for (RG int i=1;i<=len;++i) ans=ans*(ll)tong[s[i]-48]%rhl;
107         printf("%lld\n",ans); continue;
108         }
109         for (RG int i=1;i<=len;++i) hsh[i]=hsh[i-1]*base+s[i]-48;
110         for (RG int i=1;i+k-1<=len;++i){
111         Hash=hsh[i+k-1]-hsh[i-1]*bin[k];
112         ans=ans*calc(Hash)%rhl;
113         }
114         printf("%lld\n",ans);
115     }
116     }
117     return 0;
118 }

 

posted @ 2017-07-24 17:26  wfj_2048  阅读(1154)  评论(0编辑  收藏  举报