CF 580E Kefa and Watch(线段树维护hash)

题目链接:https://www.luogu.com.cn/problem/CF580E

  1 #include<bits/stdc++.h>
  2 #define ull unsigned long long
  3 using namespace std;
  4 const int N=1000011;
  5 const ull St=233,M1=1000000007,M2=1000000009;
  6 int n,m,k;
  7 ull jc[N][2],jcs[N][2];
  8 char s[N];
  9 
 10 struct Node {
 11     int l,r;
 12     ull data[2],tag[2];
 13     bool vis;
 14 };
 15 Node t[N];
 16 
 17 inline int re_ad() {
 18     char ch=getchar(); int x=0,f=1;
 19     while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
 20     while('0'<=ch && ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
 21     return x*f;
 22 }
 23 
 24 inline void init() {
 25     jc[0][0]=1,jc[0][1]=1,jcs[0][0]=1,jcs[0][1]=1;
 26     for(int i=1;i<=n;++i) (jc[i][0]=jc[i-1][0]*St)%=M1,(jc[i][1]=jc[i-1][1]*St)%=M2;
 27     for(int i=1;i<=n;++i) (jcs[i][0]=jcs[i-1][0]+jc[i][0])%=M1,(jcs[i][1]=jcs[i-1][1]+jc[i][1])%=M2;
 28 }
 29 
 30 inline void pushup(int d) {
 31     int mid=(t[d].l+t[d].r)>>1;
 32     (t[d].data[0]=t[d<<1].data[0]*jc[t[d].r-mid][0]+t[d<<1|1].data[0])%=M1;
 33     (t[d].data[1]=t[d<<1].data[1]*jc[t[d].r-mid][1]+t[d<<1|1].data[1])%=M2;
 34 }
 35 
 36 inline void pushdown(int d) {
 37     if(t[d].vis==false) return ;
 38     (t[d<<1].tag[0]=t[d].tag[0])%=M1;
 39     (t[d<<1].tag[1]=t[d].tag[1])%=M2;
 40     t[d<<1].vis=true;
 41     (t[d<<1|1].tag[0]=t[d].tag[0])%=M1;
 42     (t[d<<1|1].tag[1]=t[d].tag[1])%=M2;
 43     t[d<<1|1].vis=true;
 44     (t[d<<1].data[0]=t[d].tag[0]*jcs[t[d<<1].r-t[d<<1].l][0])%=M1;
 45     (t[d<<1].data[1]=t[d].tag[1]*jcs[t[d<<1].r-t[d<<1].l][1])%=M2;
 46     (t[d<<1|1].data[0]=t[d].tag[0]*jcs[t[d<<1|1].r-t[d<<1|1].l][0])%=M1;
 47     (t[d<<1|1].data[1]=t[d].tag[1]*jcs[t[d<<1|1].r-t[d<<1|1].l][1])%=M2;
 48     t[d].tag[0]=0,t[d].tag[1]=0,t[d].vis=false;
 49 }
 50 
 51 void build(int d,int x,int y) {
 52     t[d].l=x,t[d].r=y,t[d].vis=false;
 53     if(x==y) {
 54         (t[d].data[0]=s[x-1]-'0')%=M1;
 55         (t[d].data[1]=s[x-1]-'0')%=M2;
 56         return ;
 57     }
 58     int mid=(x+y)>>1;
 59     build(d<<1,x,mid);
 60     build(d<<1|1,mid+1,y);
 61     pushup(d);
 62 }
 63 
 64 void update(int d,int x,int y,ull z) {
 65     if(t[d].r<x || t[d].l>y) return ;
 66     if(x<=t[d].l && t[d].r<=y) {
 67         t[d].vis=true;
 68         (t[d].tag[0]=z)%=M1;
 69         (t[d].tag[1]=z)%=M2;
 70         (t[d].data[0]=z*jcs[t[d].r-t[d].l][0])%=M1;
 71         (t[d].data[1]=z*jcs[t[d].r-t[d].l][1])%=M2;
 72         return ;
 73     }
 74     pushdown(d);
 75     int mid=(t[d].l+t[d].r)>>1;
 76     if(mid>=x) update(d<<1,x,y,z);
 77     if(mid+1<=y) update(d<<1|1,x,y,z);
 78     pushup(d);
 79 }
 80 
 81 ull query1(int d,int x,int y) {
 82     if(t[d].r<x || t[d].l>y) return (ull)0;
 83     if(x<=t[d].l && t[d].r<=y) {
 84         return t[d].data[0];
 85     }
 86     pushdown(d);
 87     int mid=(t[d].l+t[d].r)>>1;
 88     ull res=0;
 89     if(mid<x) return query1(d<<1|1,x,y);
 90     else if(mid>=y) return query1(d<<1,x,y);
 91     return (query1(d<<1,x,mid)*jc[y-mid][0]+query1(d<<1|1,mid+1,y))%M1;
 92 }
 93 
 94 ull query2(int d,int x,int y) {
 95     if(t[d].r<x || t[d].l>y) return (ull)0;
 96     if(x<=t[d].l && t[d].r<=y) {
 97         return t[d].data[1];
 98     }
 99     pushdown(d);
100     int mid=(t[d].l+t[d].r)>>1;
101     ull res=0;
102     if(mid<x) return query2(d<<1|1,x,y);
103     else if(mid>=y) return query2(d<<1,x,y);
104     return (query2(d<<1,x,mid)*jc[y-mid][1]+query2(d<<1|1,mid+1,y))%M2;
105 }
106 
107 inline void Query(int x,int y,int z) {
108     if(z>y-x+1) {
109         printf("NO\n");
110         return ;
111     }
112     ull res10=query1(1,x,y-z),res11=query2(1,x,y-z);
113 //    printf("%d %d %llu %llu ",x,y-z,res10,res11);
114     ull res20=query1(1,x+z,y),res21=query2(1,x+z,y);
115 //    printf("%d %d %llu %llu\n",x+z,y,res20,res21);
116     (res10==res20 && res11==res21) ? printf("YES\n") : printf("NO\n");
117 }
118 
119 int main()
120 {
121     int goal,x,y,z;
122     n=re_ad(),m=re_ad(),k=re_ad();
123     init();
124     scanf("%s",s);
125     build(1,1,n);
126     for(int i=1;i<=m+k;++i) {
127         goal=re_ad(),x=re_ad(),y=re_ad(),z=re_ad();
128         if(goal==1) update(1,x,y,(ull)z);
129         else Query(x,y,z);
130     }
131 //    for(int i=1;i<=n;++i) printf("%llu ",jc[i]); puts("");
132 //    for(int i=1;i<=n;++i) printf("%llu ",jcs[i]); puts("");
133 //    for(int i=1;i<=10;++i) printf("%d %d %llu\n",t[i].l,t[i].r,t[i].data);
134     return 0; 
135 }

 

posted @ 2021-05-29 18:17  上官书房  阅读(51)  评论(0)    收藏  举报