Kefa and Watch

题意:

维护一个长度为n的字符串,两种操作:

1.将 [l,r] 的字符变为 c

2.询问 d 是否为 $S(l,r)$ 的周期

 

解法:

首先分析如何令 [l,r] 的周期为d,利用循环串的性质得:

只需要保证 $S(l+d,r) = S(l,r-d)$ 即可。

注意$S(l,r)$周期为 d 的定义是对于$l<=i<=r-d$有$S(i+d) = S(i)$从而,只需要维护hash即可。

应用线段树可以$O(nlogn)$

注意hash一般都要用两个模数,不然极易被卡。

好久没写hash,WA了几下。

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 
  5 #define l(x) ch[x][0]
  6 #define r(x) ch[x][1]
  7 #define N 100010
  8 #define LL unsigned long long
  9 #define P 1000000007ULL
 10 
 11 using namespace std;
 12 
 13 int totn,n,m,K;
 14 int ch[N<<1][2];
 15 char S[N];
 16 int siz[N<<1],setv[N<<1];
 17 LL power[N],power_mod[N];
 18 LL Spower[N],Spower_mod[N];
 19 LL hashv[N<<1];
 20 LL hash_mod[N<<1];
 21 
 22 void update(int x)
 23 {
 24     siz[x]=siz[l(x)]+siz[r(x)];
 25     hashv[x] = hashv[l(x)]*power[siz[r(x)]] + hashv[r(x)];
 26     hash_mod[x] = (hash_mod[l(x)]*power_mod[siz[r(x)]]%P + hash_mod[r(x)])%P;
 27 }
 28 
 29 void push(int x)
 30 {
 31     if(setv[x]==-1) return;
 32     setv[l(x)]=setv[r(x)]=setv[x];
 33     hashv[l(x)]=Spower[siz[l(x)]-1] * (LL)setv[x];
 34     hashv[r(x)]=Spower[siz[r(x)]-1] * (LL)setv[x];
 35     hash_mod[l(x)]=Spower_mod[siz[l(x)]-1] * (LL)setv[x] % P;
 36     hash_mod[r(x)]=Spower_mod[siz[r(x)]-1] * (LL)setv[x] % P;
 37     setv[x]=-1;
 38 }
 39 
 40 int build(int l,int r)
 41 {
 42     int x=++totn;
 43     setv[x]=-1;
 44     if(l==r)
 45     {
 46         hash_mod[x]=hashv[x]=S[l-1]-'0';
 47         siz[x]=1;
 48         return x;
 49     }
 50     int mid=(l+r)>>1;
 51     l(x)=build(l,mid);
 52     r(x)=build(mid+1,r);
 53     update(x);
 54     return x;
 55 }
 56 
 57 LL ask_mod(int x,int l,int r,int ql,int qr,int &sizv)
 58 {
 59     if(ql<=l && r<=qr)
 60     {
 61         sizv=siz[x];
 62         return hash_mod[x];
 63     }
 64     push(x);
 65     int mid=(l+r)>>1,tmp_sizv;
 66     if(ql<=mid && mid<qr)
 67     {
 68         sizv=0;
 69         LL tmp1=ask_mod(l(x),l,mid,ql,qr,tmp_sizv);
 70         sizv+=tmp_sizv;
 71         LL tmp2=ask_mod(r(x),mid+1,r,ql,qr,tmp_sizv);
 72         sizv+=tmp_sizv;
 73         update(x);
 74         return (tmp1*power_mod[tmp_sizv]%P+tmp2)%P;
 75     }
 76     if(ql<=mid)
 77     {
 78         LL ans=ask_mod(l(x),l,mid,ql,qr,sizv);
 79         update(x);
 80         return ans;
 81     }
 82     else
 83     {
 84         LL ans=ask_mod(r(x),mid+1,r,ql,qr,sizv);
 85         update(x);
 86         return ans;
 87     }
 88 }
 89 
 90 LL ask(int x,int l,int r,int ql,int qr,int &sizv)
 91 {
 92     if(ql<=l && r<=qr)
 93     {
 94         sizv=siz[x];
 95         return hashv[x];
 96     }
 97     push(x); 
 98     int mid=(l+r)>>1,tmp_sizv;
 99     if(ql<=mid && mid<qr)
100     {
101         sizv=0;
102         LL tmp1=ask(l(x),l,mid,ql,qr,tmp_sizv);
103         sizv+=tmp_sizv;
104         LL tmp2=ask(r(x),mid+1,r,ql,qr,tmp_sizv);
105         sizv+=tmp_sizv;
106         update(x);
107         return tmp1*power[tmp_sizv]+tmp2;
108     }
109     if(ql<=mid)
110     {
111         LL ans=ask(l(x),l,mid,ql,qr,sizv);
112         update(x);
113         return ans;
114     }
115     else
116     {
117         LL ans=ask(r(x),mid+1,r,ql,qr,sizv);
118         update(x);
119         return ans;
120     }
121 }
122 
123 void set(int x,int l,int r,int ql,int qr,int qv)
124 {
125     if(ql<=l && r<=qr)
126     {
127         setv[x] = qv;
128         hashv[x] = Spower[siz[x]-1]*(LL)setv[x];
129         hash_mod[x] = (Spower_mod[siz[x]-1] * (LL)setv[x]) % P;
130         return;
131     }
132     push(x);
133     int mid=(l+r)>>1;
134     if(ql<=mid) set(l(x),l,mid,ql,qr,qv);
135     if(mid<qr)  set(r(x),mid+1,r,ql,qr,qv);
136     update(x);
137 }
138 
139 int main()
140 {
141     power[0]=power_mod[0]=1;
142     for(int i=1;i<N;i++)
143     {
144         power[i] = power[i-1]*10ULL;
145         power_mod[i] = power_mod[i-1]*10ULL%P;
146     }
147     Spower[0]=Spower_mod[0]=1;
148     for(int i=1;i<N;i++)
149     {
150         Spower[i] = Spower[i-1] + power[i];
151         Spower_mod[i] = (Spower_mod[i-1] + power_mod[i])%P;
152     }
153     while(~scanf("%d%d%d",&n,&m,&K))
154     {
155         scanf("%s",S);
156         totn=0;
157         build(1,n);
158         int cmd,l,r,x;
159         for(int i=1;i<=m+K;i++)
160         {
161             scanf("%d%d%d%d",&cmd,&l,&r,&x);
162             if(cmd==1) set(1,1,n,l,r,x);
163             else
164             {
165                 int d=x;
166                 if(r-l+1==d)
167                 {
168                     puts("YES");
169                     continue;
170                 }
171                 if(ask(1,1,n,l+d,r,x)==ask(1,1,n,l,r-d,x)
172                     && ask_mod(1,1,n,l+d,r,x)==ask_mod(1,1,n,l,r-d,x))
173                     puts("YES");
174                 else puts("NO");
175             }
176         }
177     }
178     return 0;
179 }
180 /*
181 20 1 2
182 34075930750342906718
183 2 1 20 20
184 1 1 20 6
185 2 1 20 1
186 */
View Code

 

posted @ 2017-03-06 14:31  lawyer'  阅读(319)  评论(0编辑  收藏  举报