zoukankan      html  css  js  c++  java
  • 联赛模拟测试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;
    }
    
  • 相关阅读:
    判断一个字符串是否为回文串
    读<大道至简>软件工程实践者的思想有感
    Java学习10.23(设置页面的编码方式1)
    Java学习10.25(javaweb在界面输出2)
    【搜索】C000_LG_奶酪(bfs)
    【并查集】B001_AW_自动程序分析(不要求顺序时的离散化)
    b_aw_信息传递 & 银河英雄传说(并查集暴力求环 / 记忆化 | 带权并查集)
    b_pat_团伙头目(并查集/dfs+字符串整形互相映射)
    【堆】C003_AW_接水问题(暴力 / 堆)
    【并查集】C002_AW_樱桃网 & 打击犯罪(最下生成树 / dfs / 并查集求连通块)
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/13781944.html
Copyright © 2011-2022 走看看