题意

$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)的更多相关文章

  1. bzoj 2124 等差子序列 (线段树维护hash)

    2124: 等差子序列 Time Limit: 3 Sec  Memory Limit: 259 MBSubmit: 1922  Solved: 714[Submit][Status][Discuss ...

  2. 【拓扑 字符串还原 + 线段树维护】奇洛金卡达(father)

    奇洛金卡达(father) Description 阿良良木历将要迎来人生(不,是吸血鬼生涯)的第三次战斗——与身为人类的奇洛金卡达在直江津高中的操场solo,以取回Heartunderblade 的 ...

  3. 【NOIP模拟】board(线段树维护二进制,树序号化为二进制)

    题目背景 SOURCE:NOIP2016-RZZ-2 T3 题目描述 给出这样一棵“二叉树”: 每个节点有左右两个儿子,并如下定义每个节点的高度:假设父亲节点的高度为 h ,那么他的两个儿子的节点的高 ...

  4. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

  5. 洛谷 P7879 -「SWTR-07」How to AK NOI?(后缀自动机+线段树维护矩乘)

    洛谷题面传送门 orz 一发出题人(话说我 AC 这道题的时候,出题人好像就坐在我的右侧呢/cy/cy) 考虑一个很 naive 的 DP,\(dp_i\) 表示 \([l,i]\) 之间的字符串是否 ...

  6. 2016shenyang-1002-HDU5893-List wants to travel-树链剖分+线段树维护不同区间段个数

    肯定先无脑树链剖分,然后线段树维护一段区间不同个数,再维护一个左右端点的费用. 线段树更新,pushDown,pushUp的时候要注意考虑链接位置的费用是否相同 还有就是树链剖分操作的时候,维护上一个 ...

  7. Codeforces GYM 100114 D. Selection 线段树维护DP

    D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...

  8. [BZOJ 3995] [SDOI2015] 道路修建 【线段树维护连通性】

    题目链接:BZOJ - 3995 题目分析 这道题..是我悲伤的回忆.. 线段树维护连通性,与 BZOJ-1018 类似,然而我省选之前并没有做过  1018,即使它在 ProblemSet 的第一页 ...

  9. [BZOJ 1018] [SHOI2008] 堵塞的交通traffic 【线段树维护联通性】

    题目链接:BZOJ - 1018 题目分析 这道题就说明了刷题少,比赛就容易跪..SDOI Round1 Day2 T3 就是与这道题类似的..然而我并没有做过这道题.. 这道题是线段树维护联通性的经 ...

随机推荐

  1. java虚拟机内存溢出和泄漏实例

    测试参数设置: 1.循环调用new A()实现堆溢出,java.lang.OutOfMemoryError: Java heap space, 虚拟机参数:-Xms1M -Xmx1M -XX:+Hea ...

  2. 「LOJ#10034」「一本通 2.1 例 2」图书管理 (map

    题目描述 图书管理是一件十分繁杂的工作,在一个图书馆中每天都会有许多新书加入.为了更方便的管理图书(以便于帮助想要借书的客人快速查找他们是否有他们所需要的书),我们需要设计一个图书查找系统. 该系统需 ...

  3. Linux线程退出、资源回收、资源清理的方法

    首先说明线程中要回收哪些资源,理解清楚了这点之后在思考资源回收的问题. 1.子线程创建时从父线程copy出来的栈内存; 线程退出有多种方式,如return,pthread_exit,pthread_c ...

  4. android自动化测试之uiautomator

    1.通过monkeyrunner.bat   monkey_record.py启动MonkeyRecorder进行拿到各个控件的坐标(要连上手机才可以启动) 2.也可以通过uiautomatorvie ...

  5. 你忘记的java运算符

    当整数被0除时会得到一个无穷大,或者nan, 所以会抛出数据溢出的异常.

  6. 【218】◀▶ IDL 操作符号说明

    参考:Operators —— 运算符 01   Relational_Operators 比较运算符. 02   Mathematical_Operators 数学运算符. 03   Logical ...

  7. java定时器Timer的使用

    Time类主要负责完成定时计划任务的功能,就是在指定的时间的开始执行某个任务. Timer类的作用是设置计划任务,而封装任务内容的类是TimerTask类.此类是一个抽象类,继承需要实现一个run方法 ...

  8. Eigen::Map

    http://cherishlc.iteye.com/blog/2116800 Map类 是 矩阵库Eigen中用来将内存数据 映射为 任意形状的矩阵的类.

  9. HDU - 2036 改革春风吹满地 叉乘法求多边形面积

    改革春风吹满地 “ 改革春风吹满地, 不会AC没关系; 实在不行回老家, 还有一亩三分地. 谢谢!(乐队奏乐)” 话说部分学生心态极好,每天就知道游戏,这次考试如此简单的题目,也是云里雾里,而且,还竟 ...

  10. 如何解决启动Error:com.intellij.util.indexing.StorageException问题?

    启动tomcat时idea出现如下错误: Error:com.intellij.util.indexing.StorageException: com.intellij.util.indexing.S ...