题目:给出一个序列,有两种询问,一种是把某个区间的数全部变为一个数,一种是查询一个区间是否为以d为周期.
思路:线段树维护区间的hash值,然后对于一个区间[l,r]如果[l,r-d]和[l+d,r]相等那么这个区间的周期就是d.
注意cf上的自然溢出hash几乎必然被hack....hack方法见此文:http://codeforces.com/blog/entry/4898


/* * @author: Cwind */ #include <bits/stdc++.h> #define pb push_back #define PB pop_back #define bk back() #define se second #define fs first #define IINF (1<<29) #define sq(x) (x)*(x) #define eps 0.000000001 #define clr(x) memset((x),0,sizeof (x)) using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll,ll> P; const int maxn=1e5+399; ull H=2347; ull H2=1007; const ull mod=1e9+7; ull hashsum[maxn]; ull hashpow[maxn]; int a[maxn]; int n,m,k; const int maxp=1e6; struct Node{ int l,r; ull hash; int val,s; Node *ch[2]; bool lazy; void pushdown(){ if(r-l<=1) return; if(lazy){ lazy=0; ch[0]->lazy=ch[1]->lazy=1; ch[0]->val=ch[1]->val=val; ch[0]->hash=val*hashsum[ch[0]->s-1]%mod; ch[1]->hash=val*hashsum[ch[1]->s-1]%mod; } } }pool[maxp]; int ph=0; Node *newNode(){ Node *n=&pool[ph++]; n->lazy=0; return n; } void build(Node *n,int l,int r){ n->l=l,n->r=r; if(r-l<=1){ n->hash=a[l]; n->s=1; return; } n->ch[0]=newNode(); n->ch[1]=newNode(); Node *chl=n->ch[0],*chr=n->ch[1]; build(chl,l,(l+r)/2); build(chr,(l+r)/2,r); n->s=chr->s+chl->s; n->hash=(chl->hash+chr->hash*hashpow[chl->s]%mod)%mod; } void update(Node *n,int a,int b,int v){ n->pushdown(); int l=n->l,r=n->r; if(l>=b||a>=r) return; if(a<=l&&b>=r){ n->lazy=1; n->val=v; n->hash=v*hashsum[n->s-1]%mod; return; } Node *chl=n->ch[0],*chr=n->ch[1]; update(chl,a,b,v); update(chr,a,b,v); n->hash=(chl->hash+chr->hash*hashpow[chl->s]%mod)%mod; } ull getHash(Node *n,int a,int b){ n->pushdown(); int l=n->l,r=n->r; if(l>=b||a>=r) return 0; if(l>=a&&r<=b) return n->hash; int ll=max(a,l),rr=min(b,r); int mid=n->ch[1]->l; if(mid>ll){ return (getHash(n->ch[0],a,b)+getHash(n->ch[1],a,b)*hashpow[mid-ll])%mod; }else return getHash(n->ch[1],a,b)%mod; } void init(){ hashsum[0]=1; hashpow[0]=1; for(int i=1;i<maxn;i++){ hashsum[i]=(hashsum[i-1]*H+1)%mod; hashpow[i]=(hashpow[i-1]*H)%mod; } } Node *root; char r[maxn]; int main(){ ///freopen("/home/files/CppFiles/in","r",stdin); //freopen("defense.in","r",stdin); //freopen("defense.out","w",stdout); init(); root=newNode(); cin>>n>>m>>k; scanf("%s",r); for(int i=1;i<=n;i++){ a[i]=r[i-1]-'0'; } build(root,1,n+1); for(int ttt=0;ttt<m+k;ttt++){ int o,x,y,z; scanf("%d%d%d%d",&o,&x,&y,&z); if(o==1){ update(root,x,y+1,z); }else{ ull hash1=getHash(root,x,y-z+1); ull hash2=getHash(root,x+z,y+1); if(hash1==hash2){ puts("YES"); }else{ puts("NO"); } } } return 0; }