zoukankan      html  css  js  c++  java
  • BZOJ 3110 [Zjoi2013]K大数查询

    题解:整体二分

    以时间为关键字进行整体二分

    用线段树维护区间和

    Woc这题居然爆int,以后注意爆int的可能

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=200009;
    const int inf=1000000000;
    typedef long long Lint;
    
    int n,m;
    int ans[maxn];
    int isquery[maxn];
    
    struct SegmentTree{
    	int l,r,tag,cle;
    	Lint sum;
    }tree[maxn<<1];
    void pushup(int now){
    	tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;
    }
    void pushdown(int now){
    	if(tree[now].cle){
    		tree[now<<1].sum=tree[now<<1].tag=0;
    		tree[now<<1|1].sum=tree[now<<1|1].tag=0;
    		tree[now<<1].cle=tree[now<<1|1].cle=1;
    		tree[now].cle=0;
    	}
    	if(tree[now].tag){
    		tree[now<<1].tag+=tree[now].tag;
    		tree[now<<1|1].tag+=tree[now].tag;
    		tree[now<<1].sum+=1LL*tree[now].tag*(tree[now<<1].r-tree[now<<1].l+1);
    		tree[now<<1|1].sum+=1LL*tree[now].tag*(tree[now<<1|1].r-tree[now<<1|1].l+1);
    		tree[now].tag=0;
    	}
    }
    void BuildTree(int now,int l,int r){
    	tree[now].l=l;tree[now].r=r;
    	tree[now].tag=tree[now].sum=tree[now].cle=0;
    	if(l==r)return;
    	int mid=(l+r)>>1;
    	BuildTree(now<<1,l,mid);
    	BuildTree(now<<1|1,mid+1,r);
    }
    void Updatasec(int now,int ll,int rr,int x){
    	if(tree[now].l>=ll&&tree[now].r<=rr){
    		tree[now].tag+=x;
    		tree[now].sum+=1LL*x*(tree[now].r-tree[now].l+1);
    		return;
    	}
    	pushdown(now);
    	int mid=(tree[now].l+tree[now].r)>>1;
    	if(ll<=mid)Updatasec(now<<1,ll,rr,x);
    	if(rr>mid)Updatasec(now<<1|1,ll,rr,x);
    	pushup(now);
    }
    Lint Querysum(int now,int ll,int rr){
    	if(tree[now].l>=ll&&tree[now].r<=rr){
    		return tree[now].sum;
    	}
    	pushdown(now);
    	int mid=(tree[now].l+tree[now].r)>>1;
    	Lint ret=0;
    	if(ll<=mid)ret+=Querysum(now<<1,ll,rr);
    	if(rr>mid)ret+=Querysum(now<<1|1,ll,rr);
    	return ret;
    }
    
    struct OPTS{
    	int opty,l,r,z,t;
    }opt[maxn],q[maxn];
    int cmpt(const OPTS &rhs1,const OPTS &rhs2){
    	return rhs1.t<rhs2.t;
    }
    
    void ClearTree(){
    	tree[1].cle=1;
    	tree[1].sum=tree[1].tag=0;
    }
    
    void Div(int l,int r,int Lb,int Rb){
    //	cout<<l<<' '<<r<<' '<<Lb<<' '<<Rb<<endl;
    	if(l>r)return;
    	if(Lb==Rb){
    		for(int i=l;i<=r;++i){
    			ans[opt[i].t]=Lb;
    		}
    		return;
    	}
    	int midans=(Lb+Rb)>>1;
    	
    	ClearTree();
    	
    	int t1=l,t2=r;
    	for(int i=l;i<=r;++i){
    		if(opt[i].opty==1){
    			if(opt[i].z>midans){
    				Updatasec(1,opt[i].l,opt[i].r,1);
    				q[t2--]=opt[i];
    			}else{
    				q[t1++]=opt[i];
    			}
    		}else{
    			Lint tmp=Querysum(1,opt[i].l,opt[i].r);
    			if(tmp>=opt[i].z){
    				q[t2--]=opt[i];
    			}else{
    				opt[i].z-=tmp;
    				q[t1++]=opt[i];
    			}
    		}
    	}
    	for(int i=t1;i<=(r+t1)/2;++i){
    		swap(q[i],q[r-i+t1]);
    	}
    	for(int i=l;i<=r;++i)opt[i]=q[i];
    	Div(l,t1-1,Lb,midans);
    	Div(t1,r,midans+1,Rb);
    }
    
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;++i){
    		scanf("%d%d%d%d",&opt[i].opty,&opt[i].l,&opt[i].r,&opt[i].z);
    		opt[i].t=i;
    		if(opt[i].opty==2)isquery[i]=1;
    	}
    	BuildTree(1,1,n);
    	Div(1,m,-n,n);
    	
    	for(int i=1;i<=m;++i){
    		if(isquery[i])printf("%d
    ",ans[i]);
    	}
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    day36-20180705笔记
    day33-20180626笔记
    day31-20180612笔记
    day30-20180610笔记
    day29-20180607笔记
    day28-20180605笔记
    day26-20180531笔记
    微信开发之自定义菜单--weixin-java-tools
    几种常用的json序列化和反序列化工具介绍
    微信开发之消息接收与回复--weixin-java-tools
  • 原文地址:https://www.cnblogs.com/zzyer/p/8455036.html
Copyright © 2011-2022 走看看