http://codeforces.com/problemset/problem/580/E
https://blog.csdn.net/snowy_smile/article/details/48677011
#include<bits/stdc++.h>
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
template<class T> inline void gmax(T &a,T b){if(b>a)a=b;}
template<class T> inline void gmin(T &a,T b){if(b<a)a=b;}
using namespace std;
const int W=13,Z=1e9+7,N=1e5+10;
void fre(){
freopen("in.txt","r",stdin);
}
LL b[N],s[N];
struct A{
int l,r;
int v,w;
}a[1<<18];
void pushup(int o){
a[o].v=(a[ls].v+a[rs].v)%Z;
}
void pushdown(int o){
if(~a[o].w){
a[ls].w=a[rs].w=a[o].w;
a[ls].v=(s[a[ls].r]-s[a[ls].l-1]+Z)*a[o].w%Z;
a[rs].v=(s[a[rs].r]-s[a[rs].l-1]+Z)*a[o].w%Z;
a[o].w=-1;
}
}
void build(int o, int l, int r){
a[o].l=l;
a[o].r=r;
a[o].w=-1;
if(l==r){
char ch;scanf("%c",&ch);
int x=ch-48;
a[o].v=x*b[l]%Z;
return;
}
int m=(l+r)>>1;
build(ls,l,m);
build(rs,m+1,r);
pushup(o);
}
void change(int o, int l, int r, int w){
if (a[o].l==l&& a[o].r==r){
a[o].w=w;
a[o].v=(s[r]-s[l-1]+Z)*w%Z;
return ;
}
pushdown(o);
int m=(a[o].r+a[o].l)>>1;
if(r<=m)change(ls,l,r,w);
else if(l>m)change(rs,l,r,w);
else{
change(ls,l,m,w);
change(rs,m+1,r,w);
}
pushup(o);
}
int check(int o,int l, int r){
if(a[o].l==l&&a[o].r==r){
return a[o].v;
}
pushdown(o);
int m=(a[o].l+a[o].r)>>1;
if(r<=m)return check(ls,l,r);
else if(l>m) return check(rs,l,r);
else return (check(ls,l,m)+check(rs,m+1,r))%Z;
}
int n,m,g;
int main(){
// fre();
b[0]=0;b[1]=1;for(int i=2;i<N;i++)b[i]=b[i-1]*W%Z;
s[0]=0;s[1]=1;for(int i=2;i<N;i++)s[i]=(s[i-1]+b[i])%Z;
while(~scanf("%d%d%d",&n,&m,&g)){
getchar();
build(1,1,n);
m+=g;
while(m--){
int o,l,r,w;
scanf("%d%d%d%d",&o,&l,&r,&w);
if(o==1)change(1,l,r,w);
else{
if(r-l<w)printf("YES\n");
else{
int v1=check(1,l,r-w);v1=v1*b[w+1]%Z;
int v2=check(1,l+w,r);
if(v1==v2)printf("YES\n");
else printf("NO\n");
}
}
}
}
return 0;
}
这个题注意几点
1. 做哈希时,首先处理出每一位的哈希值
2.由于区间值会相同,因此哈希前缀有意义
3.线段树如果匹配上区间就返回,否则递归更新根区间
4.最后哈希值比较要乘哈希偏移值
#include<bits/stdc++.h>
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
template<class T> inline void gmax(T &a,T b){if(b>a)a=b;}
template<class T> inline void gmin(T &a,T b){if(b<a)a=b;}
using namespace std;
const int W=13,Z=1e9+7,N=1e5+10;
void fre(){
freopen("in.txt","r",stdin);
}
char s[N];
int main(){
// fre();
int n,m,g;
while(~scanf("%d%d%d%s",&n,&m,&g,s+1)){
m+=g;
while(m--){
int o,l,r,c;
scanf("%d%d%d%d",&o,&l,&r,&c);
if(o==1){
memset(s+l,c+'0',r-l+1);
}
else{
puts(memcmp(s+l,s+l+c,r-l-c+1)?"NO":"YES");
}
}
}
return 0;
}