CODEFORCES ROUND #321 (DIV. 2) E.Kefa and Watch(线段树+hash)
2015-10-04 20:50
453 查看
题目链接
题意:
给定n, m, k
长度为n的数字串
m+k个操作
1 l r c :把[l,r]的所有字符改成c
2 l r d :询问[l, r]的周期是否为d
所谓周期 x 就是 (1 ≤ x ≤ |s|),
if si = si + x for
all i from 1 to |s| - x)
对于每个询问输出YES或NO
思路:
若字符串S(下标为[l,len])周期为x
那么[1, len-x] == [x, len]
用线段树维护动态hash值即可
代码如下:
题意:
给定n, m, k
长度为n的数字串
m+k个操作
1 l r c :把[l,r]的所有字符改成c
2 l r d :询问[l, r]的周期是否为d
所谓周期 x 就是 (1 ≤ x ≤ |s|),
if si = si + x for
all i from 1 to |s| - x)
对于每个询问输出YES或NO
思路:
若字符串S(下标为[l,len])周期为x
那么[1, len-x] == [x, len]
用线段树维护动态hash值即可
代码如下:
#include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cmath> #include <cstring> #include <queue> #include <set> #include <map> #include <vector> using namespace std; #define Lson(x) (x << 1) #define Rson(x) (x << 1|1) #define Mid(x, y) (x + y) >> 1 #define L(x) tree[x].l #define R(x) tree[x].r #define Len(x) tree[x].len #define H(x) tree[x].hash #define La(x) tree[x].lazy typedef pair<int, int> pii; typedef long long ll; const int inf = 1e8; const int M = 311, mod = 1e9 + 7; const int N = 1e5+10; int n, m, k; int base , p[10] , a ; char str ; struct node { int l, r, len, hash, lazy; /*void put() { printf("[%d, %d], %d, %d\n", l, r, len, hash); }*/ }tree[4*N]; void init() { base[0] = 1; for(int i = 1; i < N; i++) base[i] = ((ll)base[i - 1] * M) % mod; for(int i = 0; i < 10; i++) { p[i][0] = 0; for(int j = 1; j < N; j++) { p[i][j] = ((ll)p[i][j - 1] * M % mod + i) % mod; } } } void up(int rt) { H(rt) = ((ll)H(Lson(rt)) * base[Len(Rson(rt))] % mod + H(Rson(rt))) % mod; } void go(int rt, int val) { La(rt) = val; H(rt) = p[val][Len(rt)]; } void down(int rt) { if(La(rt) != -1) { go(Lson(rt), La(rt)); go(Rson(rt), La(rt)); La(rt) = -1; } } void Build(int l, int r, int rt) { L(rt) = l, R(rt) = r, Len(rt) = r - l + 1, La(rt) = -1; //tree[rt].put(); if(l == r) { H(rt) = p[a[l]][1]; return; } int mid = Mid(l, r); Build(l, mid, Lson(rt)); Build(mid + 1, r, Rson(rt)); up(rt); } void Update(int l, int r, int rt, int L, int R, int d) { if(l >= L && r <= R) { go(rt, d); return; } down(rt); int mid = Mid(l, r); if(R <= mid) Update(l, mid, Lson(rt), L, R, d); else if(L > mid) Update(mid + 1, r, Rson(rt), L, R, d); else { Update(l, mid, Lson(rt), L , R, d); Update(mid + 1, r, Rson(rt), L, R, d); } up(rt); //tree[rt].put(); } int query(int l, int r, int rt, int L, int R) { if (l >= L && r <= R) { return H(rt); } down(rt); int mid = Mid(l, r); int ok; if (R <= mid) ok = query(l, mid, Lson(rt), L, R); else if (mid < L) ok = query(mid + 1, r, Rson(rt), L, R); else { ok = query(l, mid, Lson(rt), L, R); int rr = min(r, R); ok = ((ll)ok * base[rr-mid] % mod+ query(mid + 1, r, Rson(rt), L, R)) % mod; } up(rt); return ok; } int main() { while(~scanf("%d%d%d", &n, &m, &k)) { init(); scanf("%s", str + 1); for(int i = 1; i <= n; i++) a[i] = str[i] - '0'; int cnt; cnt = m + k; Build(1, n, 1); while(cnt--) { int x, l, r, c; scanf("%d%d%d%d", &x, &l, &r, &c); if(x == 1) { Update(1, n, 1, l, r, c); } if(x == 2) { if (l + c > r) { puts("YES"); continue;} ll ans = query(1, n, 1, l, r - c), tmp = query(1, n, 1, l + c, r); ans == tmp ? puts("YES") : puts("NO"); } } } return 0; }
相关文章推荐
- ubuntu解压缩、压缩命令
- 第二部分shell编程2正则(grepegrepsedawk)
- HTTP协议漫谈
- Uvalive 6259 Word equations dfs+dp
- Java中只有按值传递,没有按引用传递!
- Matlab-vision包学习-Feature Detection,Extraction and Matching-FAST角点检测
- 用C#开发了四天的UWP应用有感
- 第三部分shell编程3(shell脚本编写1)
- 第三部分shell编程3(shell脚本2)
- 端口详解1
- LCD1602,4位数据总线液晶屏时钟,STC12C5A60S2的10位ADC功能程序
- Android Material Design :LinearLayoutCompat添加分割线divider
- vector<int>::iterator和vector<int*>::iterator还有vector<int>*的区别
- struts2笔记
- 【重要更新】Senparc.Weixin SDK v4.3.3升级说明
- 第四部分shell编程5项目二分发系统
- 前端开发知识结构
- 软工之管理
- Android基础学习之AsyncTask(异步任务处理类)一
- 布局