2015-09-28 14:11:36 by opas
这题给的是一个字符串 把其中一些子串给取出来 判断是否是周期为d的字符串 还需要把 其中的一个区间完全变成一个数 ,然后在查询,我们把每个字符串进行hash 不管结果怎么样hash 然后进行区区间判断 。。 还是存在概率性的错误的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <algorithm> #include <string.h> #include <cstdio> #include <vector> using namespace std; typedef long long LL; const int maxn=100005; const LL mod0 =1000000007; const LL mod1 =1000000009; LL powd[2][maxn],digitpow[2][10][maxn]; void init() { powd[0][0]=powd[1][0]=1; for(LL i=1; i<=100000; i++) { powd[0][i]=( powd[0][i-1] * 10 )%mod0; powd[1][i]=( powd[1][i-1] * 10 )%mod1; for(int j=0; j<10; j++) { digitpow[0][j][i]=( digitpow[0][j][i-1]*10+j )%mod0; digitpow[1][j][i]=( digitpow[1][j][i-1]*10+j )%mod1; } } } char str[maxn]; struct Itree { LL mark[maxn*4],v[2][maxn*4],ans[2]; int cL,cR,num; void maintain(int L, int R, int o) { int mid=(L+R)>>1; v[0][o]=( v[0][o*2] * powd[0][R-mid] + v[0][o*2+1] )%mod0; v[1][o]=( v[1][o*2] * powd[1][R-mid] + v[1][o*2+1] )%mod1; } void build(int L, int R, int o) { mark[o]=-1; if(L==R){ v[0][o]=v[1][o]=str[L-1]-'0'; return ; } int mid=(L+R)>>1; build(L,mid,o*2); build(mid+1,R,o*2+1); maintain(L,R,o); } void qper(int L, int R,int n, LL &ans0,LL &ans1) { cL=L;cR=R; ans[0]=ans[1]=0;num=0; query(1,n,1); ans0=ans[0]; ans1=ans[1]; } void pushdown(int L, int R, int o) { if(mark[o]!=-1) { int mid=(L+R)>>1; mark[o*2]=mark[o*2+1]=mark[o]; v[0][o*2]=digitpow[0][mark[o]][ mid-L+1 ]; v[1][o*2]=digitpow[1][mark[o]][ mid-L+1 ]; v[0][o*2+1]=digitpow[0][mark[o]][ R-mid ]; v[1][o*2+1]=digitpow[1][mark[o]][ R-mid ]; mark[o]=-1; } } void query(int L, int R, int o) { if(cL<=L&&R<=cR) { ans[0]=(ans[0]*powd[0][R-L+1]+v[0][o])%mod0; ans[1]=(ans[1]*powd[1][R-L+1]+v[1][o])%mod1; return ; } pushdown(L,R,o); int mid=(L+R)>>1; if(cL<=mid)query(L,mid,o*2); if(cR>mid)query(mid+1,R,o*2+1); } void update(int L, int R, int o) { if(cL<=L&&R<=cR) { mark[o]=num; v[0][o]=digitpow[0][num][R-L+1]; v[1][o]=digitpow[1][num][R-L+1]; return ; } pushdown(L,R,o); int mid=(L+R)>>1; if(cL<=mid)update(L,mid,o*2); if(cR>mid)update(mid+1,R,o*2+1); maintain(L,R,o); } }T; int main() { init(); int n,m,k; while(scanf("%d%d%d",&n,&m,&k)==3) { scanf("%s",str); T.build(1,n,1); m+=k; while(m--){ int op,L,R,V; scanf("%d%d%d%d",&op,&L,&R,&V); if(op==1){ T.cL=L;T.cR=R; T.num=V; T.update(1,n,1); }else{ if((R-L+1)<=V){ puts("YES"); }else if( ( R - L + 1 ) <= 2 * V ) { int len=R-L+1-V; LL a10,a11,a20,a21; T.qper(L,L+len-1,n,a10,a11); T.qper(R-len+1,R,n,a20,a21); if(a10==a20&&a11==a21) puts("YES"); else puts("NO"); }else { if((R-L+1)%V == 0){ int d=(R-L+1)/V; int len = (d-1)*V; LL a10,a11,a20,a21; T.qper(L,L+len-1,n,a10,a11); T.qper(R-len+1,R,n,a20,a21); if(a10==a20&&a11==a21) puts("YES"); else puts("NO"); } else{ int d=(R-L+1)/V; int len = (d-1)*V; int tail=(R-L+1)-V*d; LL a10,a11,a20,a21; T.qper(L,L+len-1,n,a10,a11); T.qper(L+V,L+V+len-1,n,a20,a21); if(a10==a20&&a11==a21) { T.qper(L,L+tail-1,n,a10,a11); T.qper(R-tail+1,R,n,a20,a21); if(a10==a20&&a11==a21) puts("YES"); else puts("NO"); } else puts("NO"); } } } } } return 0; }