联赛模拟测试11 D. 甜圈 线段树维护哈希值

题目描述



分析

思想很巧妙
对于一个甜甜圈,我们维护它的加工顺序的哈希值
在所有的操作都结束后
我们判断该哈希值是否和 (1,2,...k) 的哈希值相等即可

代码

#include<cstdio>
#define rg register
#define ull unsigned long long
const int maxn=1e6+5;
const ull bas=233;
inline int read(){
	rg int x=0,fh=1;
	rg char ch=getchar();
	while(ch<'0' || ch>'9'){
		if(ch=='-') fh=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*fh;
}
struct trr{
	int l,r,siz;
	ull ans,lazj,lazc;
	trr(){
		l=r=0;
		lazc=1;
		ans=lazj=0;
	}
}tr[maxn];
void build(int da,int l,int r){
	tr[da].l=l,tr[da].r=r,tr[da].siz=r-l+1;
	if(tr[da].l==tr[da].r) return;
	rg int mids=(tr[da].l+tr[da].r)>>1;
	build(da<<1,l,mids);
	build(da<<1|1,mids+1,r);
}
void push_up(int da){
	tr[da].ans=tr[da<<1].ans+tr[da<<1|1].ans;
}
void push_down(int da){
	if(tr[da].lazc!=1){
		tr[da<<1].lazc*=tr[da].lazc;
		tr[da<<1|1].lazc*=tr[da].lazc;
		tr[da<<1].lazj*=tr[da].lazc;
		tr[da<<1|1].lazj*=tr[da].lazc;
		tr[da<<1].ans*=tr[da].lazc;
		tr[da<<1|1].ans*=tr[da].lazc;
		tr[da].lazc=1;
	}
	if(tr[da].lazj!=0){
		tr[da<<1].lazj+=tr[da].lazj;
		tr[da<<1|1].lazj+=tr[da].lazj;
		tr[da<<1].ans+=tr[da].lazj*tr[da<<1].siz;
		tr[da<<1|1].ans+=tr[da].lazj*tr[da<<1|1].siz;
		tr[da].lazj=0;
	}
}
void ad(int da,int l,int r,ull val){
	if(tr[da].l>=l && tr[da].r<=r){
		tr[da].ans+=val*tr[da].siz;
		tr[da].lazj+=val;
		return;
	}
	push_down(da);
	rg int mids=(tr[da].l+tr[da].r)>>1;
	if(l<=mids) ad(da<<1,l,r,val);
	if(r>mids) ad(da<<1|1,l,r,val);
	push_up(da);
}
void cheng(int da,int l,int r,ull val){
	if(tr[da].l>=l && tr[da].r<=r){
		tr[da].lazj*=val;
		tr[da].lazc*=val;
		tr[da].ans*=val;
		return;
	}
	push_down(da);
	rg int mids=(tr[da].l+tr[da].r)>>1;
	if(l<=mids) cheng(da<<1,l,r,val);
	if(r>mids) cheng(da<<1|1,l,r,val);
	push_up(da);
}
ull cx(int da,int wz){
	if(tr[da].l==tr[da].r){
		return tr[da].ans;
	}
	push_down(da);
	rg int mids=(tr[da].l+tr[da].r)>>1;
	if(wz<=mids) return cx(da<<1,wz);
	else return cx(da<<1|1,wz);
}
int n,k,t;
int main(){
	freopen("deco.in","r",stdin);
	freopen("deco.out","w",stdout);
	n=read(),k=read(),t=read();
	build(1,1,n);
	rg int l,r,val;
	for(rg int i=1;i<=t;i++){
		l=read(),r=read(),val=read();
		cheng(1,l,r,bas);
		ad(1,l,r,val);
	}
	rg ull ans=0;
	for(rg int i=1;i<=k;i++){
		ans=ans*bas+i;
	}
	rg int cnt=0;
	for(rg int i=1;i<=n;i++){
		ull nans=cx(1,i);
		if(ans==nans) cnt++;
	}
	printf("%d
",cnt);
	return 0;
}
原文地址:https://www.cnblogs.com/liuchanglc/p/13781944.html