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

 

转载于:https://www.cnblogs.com/lawyer/p/6509843.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值