线段树 CodeForces 580E

线段树上的hash...

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

#define lson o << 1, L, mid
#define rson o << 1 | 1, mid+1, R
#define ls o << 1
#define rs o << 1 | 1
const int mod = 1e9+7;
const int maxn = 100005;
const LL x = 1e6+3;

LL sum[maxn << 2];
LL lazy[maxn << 2];
LL xp[maxn];
LL xp_sum[maxn];
char a[maxn];
int n, m;

void pushup(int o, int L, int R)
{
	int mid = (L + R) >> 1;
	sum[o] = (sum[ls] + sum[rs] * xp[mid - L + 1]) % mod;
}

void pushdown(int o, int L, int R)
{
	if(lazy[o]) {
		int mid = (L + R) >> 1;
		sum[ls] = lazy[o] * xp_sum[mid-L] % mod;
		sum[rs] = lazy[o] * xp_sum[R-mid-1] % mod; 
		lazy[ls] = lazy[rs] = lazy[o];
		lazy[o] = 0;
	}
}

void build(int o, int L, int R)
{
	lazy[o] = 0;
	if(L == R) {
		sum[o] = a[L];
		return;
	}
	int mid = (L + R) >> 1;
	build(lson);
	build(rson);
	pushup(o, L, R);
}

void update(int o, int L, int R, int ql, int qr, int v)
{
	if(ql <= L && qr >= R) {
		sum[o] = xp_sum[R-L] * v % mod;
		lazy[o] = v;
		return;
	}
	pushdown(o, L, R);
	int mid = (L + R) >> 1;
	if(ql <= mid) update(lson, ql, qr, v);
	if(qr > mid) update(rson, ql, qr, v);
	pushup(o, L, R);
}

LL query(int o, int L, int R, int ql, int qr)
{
	if(ql <= L && qr >= R) return sum[o];
	pushdown(o, L, R);
	int mid = (L + R) >> 1;
	if(ql > mid) return query(rson, ql, qr);
	else if(qr <= mid) return query(lson, ql, qr);
	else {
		LL t1 = query(lson, ql, qr);
		LL t2 = query(rson, ql, qr);
		int tt = mid - max(ql, L) + 1;
		return (t1 + t2 * xp[tt]) % mod;
	}
	pushup(o, L, R);
}

void init()
{
	xp[0] = xp_sum[0] = 1;
	for(int i = 1; i < maxn; i++) xp[i] = xp[i-1] * x % mod, xp_sum[i] = (xp_sum[i-1] + xp[i]) % mod;
}

void work()
{
	int k;
	scanf("%d%d%d", &n, &m, &k);
	m += k;
	scanf("%s", a+1);
	for(int i = 1; i <= n; i++) a[i] = a[i] - '0' + 1;
	build(1, 1, n);
	while(m--) {
		int op, ql, qr, c;
		scanf("%d%d%d%d", &op, &ql, &qr, &c);
		if(op == 1) {
			c++;
			update(1, 1, n, ql, qr, c);
		}
		else {
			if(c == qr - ql + 1) {
				printf("YES\n");
				continue;
			}
			LL t1 = query(1, 1, n, ql, qr-c);
			LL t2 = query(1, 1, n, ql+c, qr);
			if(t1 == t2) printf("YES\n");
			else printf("NO\n");
		}
	}
}

int main()
{
//freopen("data", "r", stdin);
	init();
	work();
	
	return 0;
}


你可能感兴趣的:(线段树)