G Caesar Cipher 哈希+线段树 ccpc 威海

G Caesar Cipher 哈希+线段树 ccpc 威海

题解:

容易发现直接暴力更新即可,因为每次只更新1,所以最多暴力更新10次nlogn,然后询问就转化为哈希即可。

#include <bits/stdc++.h>
#define lson (id<<1)
#define rson (id<<1|1)
using namespace std;
const int maxn = 5e5+10;
typedef long long ll;
const int mod = 1e9+7;
const int base = 65537;
const int val = 65535;
int a[maxn];
ll sum[maxn<<2],maxs[maxn<<2],lazy[maxn<<2],p[maxn],pre[maxn<<2];
void push_up(int id){
	sum[id] = (sum[lson]+sum[rson])%mod;
	maxs[id] = max(maxs[lson],maxs[rson]);
}
void build(int id,int l,int r){
	lazy[id] = 0;
	if(l==r) {
		pre[id] = p[l];
		maxs[id] = a[l];
		sum[id] = a[l]*p[l]%mod;
		return ;
	}
	int mid = (l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
	push_up(id);
	pre[id] = (pre[lson]+pre[rson])%mod;
}
void push_down(int id){
	if(lazy[id]==0) return ;
	maxs[lson]+= lazy[id];
	maxs[rson]+=lazy[id];
	sum[lson] += lazy[id]*pre[lson]%mod;
	sum[rson] += lazy[id]*pre[rson]%mod;
	lazy[lson] += lazy[id];
	lazy[rson] += lazy[id];
	sum[lson]%=mod,sum[rson]%=mod;
	lazy[id] = 0;
}
void update(int id,int l,int r,int x,int y){
	if(maxs[id]<val&&x<=l&&y>=r) {
		lazy[id] += 1;
		maxs[id] += 1;
		sum[id] = (sum[id] + pre[id])%mod;
		return ;
	}
	if(l==r){
		maxs[id] = sum[id] = 0;
		return ;
	}
	push_down(id);
	int mid = (l+r)>>1;
	if(x<=mid) update(lson,l,mid,x,y);
	if(y>mid) update(rson,mid+1,r,x,y);
	push_up(id);
}
ll query(int id,int l,int r,int x,int y){
	if(x<=l&&y>=r) return sum[id];
	ll ans = 0;
	int mid = (l+r)>>1;
	push_down(id);
	if(x<=mid) ans += query(lson,l,mid,x,y);
	if(y>mid) ans += query(rson,mid+1,r,x,y);
	ans %= mod;
	return ans;
}
void init(){
	p[0] = 1;
	for(int i=1;i<maxn;i++) p[i] = p[i-1]*base%mod;
}
int main(){
	init();
	int n,q;
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	build(1,1,n);
	while(q--){
		int op,x,y,L;
		scanf("%d%d%d",&op,&x,&y);
		if(op==1){
			update(1,1,n,x,y);
		}
		else{
			scanf("%d",&L);
			ll sum1 = query(1,1,n,x,x+L-1),sum2 = query(1,1,n,y,y+L-1);
			// printf("??:sum1 = %lld sum2 = %lld\n", sum1,sum2);
			if(x<y) sum1 = sum1 * p[y-x]%mod;
			else sum2 = sum2 * p[x-y]%mod;
			// printf("sum1 = %lld sum2 = %lld\n", sum1,sum2);
			if(sum1==sum2) printf("yes\n");
			else printf("no\n");
		}
	}
	return 0;
}


posted @ 2020-10-30 09:00  EchoZQN  阅读(106)  评论(0编辑  收藏  举报