用线段树维护哈希,类似于进位制的一个哈希 a[i]*p^i+a[i-1]*p^i-1...

然后,线段树存在某区间的哈希的值,对于更新,则只需提前计算出整段的哈希值即可。

判断是否相等,由于相隔为d,只需计算(l+d,r),(l,r-d)两段哈希的值是否相等即可。为了防止一次哈希可能使不符合条件的值哈希值相等,所以进行了两次哈希。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define LL long long
using namespace std; const int MAX=100010;
const LL m1=1000000007;
const LL m2=1000000009;
const int g1=47;
const int g2=67; char str[MAX]; struct HASH{
LL seg[MAX<<2]; int lazy[MAX<<2];
LL bits[10][MAX]; LL mod,gt; LL ebit[MAX];
void init(LL m,LL g){
mod=m; gt=g;
for(int i=0;i<MAX;i++){
if(i==0) ebit[i]=1;
else {
ebit[i]=(ebit[i-1]*gt)%mod;
}
}
for(int i=0;i<=9;i++){
bits[i][0]=0;
for(int j=1;j<MAX;j++){
bits[i][j]=(bits[i][j-1]*gt%mod+i)%mod;
}
}
}
void push_up(int rt,int l,int r){
seg[rt]=(seg[rt<<1|1]+seg[rt<<1]*ebit[r-(l+r)/2])%mod;
}
void push_down(int rt,int l,int r){
if(lazy[rt]!=-1){
int m=(l+r)>>1;
lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
seg[rt<<1]=bits[lazy[rt]][m-l+1];
seg[rt<<1|1]=bits[lazy[rt]][r-m];
lazy[rt]=-1;
}
}
void build(int rt,int l,int r){
if(l==r){
seg[rt]=(str[l]-'0')%mod;
lazy[rt]=-1;
return ;
}
int m=(l+r)>>1;
build(rt<<1,l,m);
build(rt<<1|1,m+1,r);
push_up(rt,l,r);
lazy[rt]=-1;
}
void update(int rt,int l,int r,int L,int R,int d){
if(l<=L&&R<=r){
lazy[rt]=d;
seg[rt]=bits[d][R-L+1];
return ;
}
int m=(L+R)>>1;
push_down(rt,L,R);
if(m>=l)
update(rt<<1,l,r,L,m,d);
if(m+1<=r)
update(rt<<1|1,l,r,m+1,R,d);
push_up(rt,L,R);
}
void query(int rt ,int l,int r,int L,int R,LL &res){
if(l<=L&&R<=r){
res=(res*ebit[R-L+1]+seg[rt])%mod;
return ;
}
push_down(rt,L,R);
int m=(L+R)>>1;
if(m>=l)
query(rt<<1,l,r,L,m,res);
if(m+1<=r) query(rt<<1|1,l,r,m+1,R,res);
} bool check(int l,int r,int d,int n){
if(r-l+1==d) return true;
LL lrt=0; query(1,l,r-d,1,n,lrt);
LL rrt=0; query(1,l+d,r,1,n,rrt);
if(lrt==rrt) return true;
return false;
}
}a,b; int main(){
// cout<<"OK"<<endl;
int n,m,k,op,l,r,d;
// cout<<"OK"<<endl;
// HASH a,b;
/// cout<<"OK"<<endl;
while(scanf("%d%d%d",&n,&m,&k)!=EOF){
scanf("%s",str+1);
a.init(m1,g1);
b.init(m2,g2);
a.build(1,1,n);
b.build(1,1,n);
/// cout<<"YES"<<endl;
m+=k;
while(m--){
scanf("%d%d%d%d",&op,&l,&r,&d);
if(op==1){
a.update(1,l,r,1,n,d);
b.update(1,l,r,1,n,d);
}
else{
if(a.check(l,r,d,n)&&b.check(l,r,d,n)){
puts("YES");
}
else puts("NO") ;
}
}
}
return 0;
}

CF #321 (Div. 2) E的更多相关文章

  1. CF #321 (Div. 2) D

    不说了,爆内存好几次,后来醒起状态有重复... 状压+TSP #include <iostream> #include <cstdio> #include <cstrin ...

  2. CF #376 (Div. 2) C. dfs

    1.CF #376 (Div. 2)    C. Socks       dfs 2.题意:给袜子上色,使n天左右脚袜子都同样颜色. 3.总结:一开始用链表存图,一直TLE test 6 (1)如果需 ...

  3. CF #375 (Div. 2) D. bfs

    1.CF #375 (Div. 2)  D. Lakes in Berland 2.总结:麻烦的bfs,但其实很水.. 3.题意:n*m的陆地与水泽,水泽在边界表示连通海洋.最后要剩k个湖,总要填掉多 ...

  4. CF #374 (Div. 2) D. 贪心,优先队列或set

    1.CF #374 (Div. 2)   D. Maxim and Array 2.总结:按绝对值最小贪心下去即可 3.题意:对n个数进行+x或-x的k次操作,要使操作之后的n个数乘积最小. (1)优 ...

  5. CF #374 (Div. 2) C. Journey dp

    1.CF #374 (Div. 2)    C.  Journey 2.总结:好题,这一道题,WA,MLE,TLE,RE,各种姿势都来了一遍.. 3.题意:有向无环图,找出第1个点到第n个点的一条路径 ...

  6. CF #371 (Div. 2) C、map标记

    1.CF #371 (Div. 2)   C. Sonya and Queries  map应用,也可用trie 2.总结:一开始直接用数组遍历,果断T了一发 题意:t个数,奇变1,偶变0,然后与问的 ...

  7. CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组

    题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum 题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有 ...

  8. CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组(转)

    转载自:http://www.cnblogs.com/icode-girl/p/5744409.html 题目链接:CF #365 (Div. 2) D - Mishka and Interestin ...

  9. CF#138 div 1 A. Bracket Sequence

    [#138 div 1 A. Bracket Sequence] [原题] A. Bracket Sequence time limit per test 2 seconds memory limit ...

随机推荐

  1. JavaScript中的 函数splice() 的使用。

    大二接触JavaScript初期,学习函数中有一道题: 定义一个2个参数的函数.第1个参数是一个数组,第2个参数是需要删除的元素.函数功能,在第1个实参数组中查找第2个实参提供的值,找到则删除该元素( ...

  2. 01--Java集合知识

    一.Java集合概览 Java中集合分2大块,Collection和Map,分别代表不同功能的集合类对象,整体结构图如下: Collection├List│├LinkedList│├ArrayList ...

  3. HashMap , TreeMap , TreeMap 默认排序

    Java代码  import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java. ...

  4. PHP7安装Memcache+Memcached缓存加速WordPress教程

    PHP7安装Memcache+Memcached缓存加速WordPress教程 2016年1月19日 6,691 Views 生活方式 PHP7最显著的变化就是性能的极大提升,已接近Facebook开 ...

  5. (转)分布式文件存储FastDFS(六)FastDFS多节点配置

    http://blog.csdn.net/xingjiarong/article/details/50759918 前面几篇关于FastDFS的博客中介绍了如何在一台机器上搭建一个简易的FastDFS ...

  6. Python 之lxml解析库

    一.XPath常用规则 二.解析html文件 from lxml import etree # 读取HTML文件进行解析 def parse_html_file(): html = etree.par ...

  7. (Entity framework 应用篇)把权限判断封装在数据库访问层

    这里,我只是以一个例子,说一下简单权限控制,通过这个例子,大家可以设计庞大的权限管理层,把权限控制封装到数据库访问层,这样程序员就不用再写权限判断的代码了 首先,先看看我数据库DBContext的定义 ...

  8. 网络爬虫 robots协议 robots.txt

    网络爬虫 网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成.传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上 ...

  9. pandas格式化str为时间,pandas将int转化为str

    code_300['HISTORY_DATE'] = code_300['HISTORY_DATE'].map(str)code_300['HISTORY_DATE'] = pd.to_datetim ...

  10. Django - ORM创建基本类

    DBFirst CodeFirst 创建类 1.根据类自动创建数据库表 在app下的models.py中创建表 创建数据库之前,需要在django下的setting.py模块中的INSTALLED_A ...