cf580E. Kefa and Watch(线段树维护字符串hash)
题意
$n$个数的序列,$m + k$种操作
1、$l , r, k$把$l - r$赋值为$k$
2、$l, r, d$询问$l - r$是否有长度为$d$的循环节
Sol
首先有个神仙结论:若询问区间为$(l, r, d)$,则只需判断$(l + d, r)$和$(l, r - d )$是否相同
证明可以用归纳法。
然后线段树维护一下字符串hash值,维护一个区间覆盖的标记就好了
注意赋值的时候有$0$的情况,因此开始的标记不能为$0$
#include<cstdio>
#include<algorithm>
#define int long long
#define LL long long
#define ull long long
using namespace std;
const int MAXN = 1e6 + ;
const double eps = 1e-;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
int N, M, K;
char s[MAXN];
struct Segment {
ull sum[MAXN], po[MAXN], seed, mod;
#define ls k << 1
#define rs k << 1 | 1
struct Node {
int l, r, siz;
ull ha, f;
}T[MAXN];
void update(int k) {
T[k].ha = (T[ls].ha % mod + po[T[ls].siz] * T[rs].ha % mod) % mod;
}
void ps(int k, int son) {
T[son].f = T[k].f;
T[son].ha = sum[T[son].siz - ] * T[son].f % mod;
}
void pushdown(int k) {
if(T[k].f == -) return ;
ps(k, ls); ps(k, rs);
T[k].f = -;
}
void Build(int k, int ll, int rr) {
T[k] = (Node) {ll, rr, rr - ll + , , -};
if(ll == rr) {
T[k].ha = s[ll] - '';
return ;
}
int mid = T[k].l + T[k].r >> ;
Build(ls, ll, mid); Build(rs, mid + , rr);
update(k);
}
void IntervalChange(int k, int ll, int rr, ull val) {
if(ll <= T[k].l && T[k].r <= rr) {
T[k].f = val % mod;
T[k].ha = sum[T[k].siz - ] * val % mod;
return ;
}
pushdown(k);
int mid = T[k].l + T[k].r >> ;
if(ll <= mid) IntervalChange(ls, ll, rr, val);
if(rr > mid) IntervalChange(rs, ll, rr, val);
update(k);
}
ull IntervalQuery(int k, int ll, int rr) {
if(ll > rr) return ;
if(ll <= T[k].l && T[k].r <= rr) return T[k].ha % mod;
pushdown(k);
int mid = T[k].l + T[k].r >> ;
if(ll > mid) return IntervalQuery(rs, ll, rr) % mod;
else if(rr <= mid) return IntervalQuery(ls, ll, rr) % mod;
else return (IntervalQuery(ls, ll, rr) % mod + po[mid - max(T[k].l, ll) + ] * IntervalQuery(rs, ll, rr) % mod) % mod;
}
void work() {
po[] = ; sum[] = ;
for(int i = ; i <= N; i++) po[i] = po[i - ] * seed % mod, sum[i] = (sum[i - ] + po[i]) % mod;
Build(, , N);
}
int Query(int l, int r, int k) {
return IntervalQuery(, l, r - k) == IntervalQuery(, l + k, r);
}
}Se[]; main() {
Se[].seed = ; Se[].mod = 1e9 + ;
Se[].seed = ; Se[].mod = 1e9 + ;
N = read(); M = read(); K = read();
scanf("%s", s + );
Se[].work(); Se[].work();
for(int i = ; i <= M + K; i++) {
int opt = read(), l = read(), r = read(), k = read();
if(opt == ) Se[].IntervalChange(, l, r, k), Se[].IntervalChange(, l, r, k);
else {
if((r - l + ) == k) {
puts("YES");
continue;
}
puts((Se[].Query(l, r, k) && Se[].Query(l, r, k))? "YES" : "NO");
}
}
return ;
}
cf580E. Kefa and Watch(线段树维护字符串hash)的更多相关文章
- bzoj 2124 等差子序列 (线段树维护hash)
2124: 等差子序列 Time Limit: 3 Sec Memory Limit: 259 MBSubmit: 1922 Solved: 714[Submit][Status][Discuss ...
- 【拓扑 字符串还原 + 线段树维护】奇洛金卡达(father)
奇洛金卡达(father) Description 阿良良木历将要迎来人生(不,是吸血鬼生涯)的第三次战斗——与身为人类的奇洛金卡达在直江津高中的操场solo,以取回Heartunderblade 的 ...
- 【NOIP模拟】board(线段树维护二进制,树序号化为二进制)
题目背景 SOURCE:NOIP2016-RZZ-2 T3 题目描述 给出这样一棵“二叉树”: 每个节点有左右两个儿子,并如下定义每个节点的高度:假设父亲节点的高度为 h ,那么他的两个儿子的节点的高 ...
- codeforces Good bye 2016 E 线段树维护dp区间合并
codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...
- 洛谷 P7879 -「SWTR-07」How to AK NOI?(后缀自动机+线段树维护矩乘)
洛谷题面传送门 orz 一发出题人(话说我 AC 这道题的时候,出题人好像就坐在我的右侧呢/cy/cy) 考虑一个很 naive 的 DP,\(dp_i\) 表示 \([l,i]\) 之间的字符串是否 ...
- 2016shenyang-1002-HDU5893-List wants to travel-树链剖分+线段树维护不同区间段个数
肯定先无脑树链剖分,然后线段树维护一段区间不同个数,再维护一个左右端点的费用. 线段树更新,pushDown,pushUp的时候要注意考虑链接位置的费用是否相同 还有就是树链剖分操作的时候,维护上一个 ...
- Codeforces GYM 100114 D. Selection 线段树维护DP
D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...
- [BZOJ 3995] [SDOI2015] 道路修建 【线段树维护连通性】
题目链接:BZOJ - 3995 题目分析 这道题..是我悲伤的回忆.. 线段树维护连通性,与 BZOJ-1018 类似,然而我省选之前并没有做过 1018,即使它在 ProblemSet 的第一页 ...
- [BZOJ 1018] [SHOI2008] 堵塞的交通traffic 【线段树维护联通性】
题目链接:BZOJ - 1018 题目分析 这道题就说明了刷题少,比赛就容易跪..SDOI Round1 Day2 T3 就是与这道题类似的..然而我并没有做过这道题.. 这道题是线段树维护联通性的经 ...
随机推荐
- codevs 3027线段覆盖2
传送门 3027 线段覆盖 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 数轴上有n条线段,线段的两端都是整数坐标, ...
- C语言之数组与指针的易混淆知识点
一.指针与数组 指针:指针本身也是一个变量,它的内容是指向的内容的地址.指针同样有类型的区分,char 的指针只能指向char型数据,int 指针指向int型数据.但是指针所占内存单元的大小(即其内容 ...
- mysql跨表更新示例
一.在同一个表中冗余存储记录之间的关系(组织机构树),查询时需要根据冗余字段进行关联查询 例如,下面的示例,用户表中有个字段friend标记其朋友关系,要求找出id=2及他的朋友(父节点) mysql ...
- 什么是weex
Weex是一个使用web开发体验来开发高性能原生应用的框架 在集成WeexSDK之后,你可以使用javaScript和现代流行的前端框架来开发移动应用. Weex的结构是解耦的,渲染引擎与语法层是分开 ...
- ceph部署与问题
一.基本情况:物理设备:4台惠普dl360,4个千兆网卡 4个1T盘操作系统统一为:CentOS 7.2.1511ceph版本:10.2.3ceph-deploy版本:1.5.36网络情况:192.1 ...
- ThinkPHP3.2.3中,查询语句中in的使用方法。
//删除分类 public function del(){ $cid = I('get.cid'); $cate = M('category')->field('cid,pid')->se ...
- Qt-MVC图形视图框架分解
前面在<Qt-MVC图形视图框架出识>中我们了解了Qt图形视图框架中三个最基本的类,弄清他们的关系,本片小文,我们将对QGraphicsView,QGraphiceScene,QGraph ...
- 使用you-get下载网页小视频(实际上你可以下载任意你想要的web网页中的内容)
1. 什么是you-get? You-Get是一个小型的命令行实用程序,用于从Web下载媒体内容(视频,音频,图像),如果没有其他方便的方法可以尝试使用you-get. 2.安装you-get 打开命 ...
- node中的url模块解析结果
1. URL模块作用: url 模块用于处理与解析 URL. 使用方法如下: const url = require('url'); 2. URL 字符串与 URL 对象 URL 字符串是结构化的字符 ...
- 436. Find Right Interval
Given a set of intervals, for each of the interval i, check if there exists an interval j whose star ...