您的位置:首页 > 其它

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值即可

代码如下:

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: