# LOJ#2303. 「NOI2017」蚯蚓排队

$n \leq 200000$的$1 \leq a_i \leq 6$的蚯蚓，有三种操作：让一只队头蚯蚓接在一只队尾蚯蚓后面；让一队蚯蚓从某个蚯蚓后面断成两队；问：给个字符串，问他的。。算了你们直接看题吧

  1 //#include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 //#include<math.h>
5 //#include<set>
6 //#include<queue>
7 //#include<bitset>
8 //#include<vector>
9 #include<algorithm>
10 #include<stdlib.h>
11 using namespace std;
12
13 #define LL long long
15 {
16     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
17     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
18 }
19
20 //Pay attention to '-' , LL and double of qread!!!!
21
22 int n,m;
23 #define maxn 200011
24 #define maxh 1000007
25 int a[maxn],bb[55]; LL cc[55];
26
27 struct Hash
28 {
29     struct Edge{LL to; int v,next;}edge[maxn*50]; int first[maxh],le;
30     Hash() {le=2;}
31     void in(LL x,int h,int v)
32     {
33         for (int i=first[h];i;i=edge[i].next)
34         {
35             Edge &e=edge[i];
36             if (e.to==x) {e.v+=v; return;}
37         }
38         Edge &e=edge[le]; e.to=x; e.v=1; e.next=first[h]; first[h]=le++;
39     }
40     int find(LL x,int h)
41     {
42         for (int i=first[h];i;i=edge[i].next)
43         {
44             Edge &e=edge[i];
45             if (e.to==x) return e.v;
46         }
47         return 0;
48     }
49 }h;
50
51 int Nxt[maxn],Pre[maxn];
52 char s[maxn*50]; int len;
53 int main()
54 {
55     bb[0]=1; for (int i=1;i<=50;i++) bb[i]=bb[i-1]*7%maxh;
56     cc[0]=1; for (int i=1;i<=50;i++) cc[i]=cc[i-1]*7;
58     for (int i=1;i<=n;i++) {Pre[i]=Nxt[i]=0; a[i]=qread(); h.in(a[i],a[i],1);}
59     int op; char c; int x,y;
60     while (m--)
61     {
63         if (op==1)
64         {
66             Nxt[x]=y; Pre[y]=x;
67             LL B=0,C=0;
68             for (int i=x,cnt=49,w=0;cnt && i;i=Pre[i],w++,cnt--)
69             {
70                 B=(B+1ll*a[i]*bb[w])%maxh;
71                 C=C+1ll*a[i]*cc[w];
72                 LL nb=B,nc=C;
73                 for (int j=y,k=1;j && k<=cnt;j=Nxt[j],k++)
74                 {
75                     nb=(nb*7+a[j])%maxh;
76                     nc=nc*7+a[j];
77                     h.in(nc,nb,1);
78                 }
79             }
80         }
81         else if (op==2)
82         {
84             Nxt[x]=0; Pre[y]=0;
85             LL B=0,C=0;
86             for (int i=x,cnt=49,w=0;cnt && i;i=Pre[i],w++,cnt--)
87             {
88                 B=(B+1ll*a[i]*bb[w])%maxh;
89                 C=C+1ll*a[i]*cc[w];
90                 LL nb=B,nc=C;
91                 for (int j=y,k=1;j && k<=cnt;j=Nxt[j],k++)
92                 {
93                     nb=(nb*7+a[j])%maxh;
94                     nc=nc*7+a[j];
95                     h.in(nc,nb,-1);
96                 }
97             }
98         }
99         else if (op==3)
100         {
101             len=0;
102             while ((c=getchar())<'0' || c>'9');
103             do s[++len]=c; while ((c=getchar())>='0' && c<='9');
105             LL B=0,C=0;
106             for (int i=1;i<x;i++) B=(B*7+s[i]-'0')%maxh,C=C*7+s[i]-'0';
107             int ans=1;
108             for (int i=x;i<=len;i++)
109             {
110                 B=(B*7+s[i]-'0')%maxh; C=C*7+s[i]-'0';
111                 ans=1ll*ans*h.find(C,B)%998244353;
112                 B=(B-(s[i-x+1]-'0')*bb[x-1])%maxh+maxh; B%=maxh;
113                 C=C-(s[i-x+1]-'0')*cc[x-1];
114             }
115             printf("%d\n",ans);
116         }
117     }
118     return 0;
119 }
View Code

posted @ 2018-06-20 20:11  Blue233333  阅读(272)  评论(0编辑  收藏  举报