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 */