CODEFORCES ROUND #321 (DIV. 2) E.Kefa and Watch(線段樹+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[N], p[10][N], a[N];
char str[N];

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;
}



發佈了102 篇原創文章 · 獲贊 7 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章