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

    刚刚学习了整体二分,练习一下。

    太长时间没写线段树了,结果在这道题里,线段树没有写update函数,怎么调都调不出来,无奈只好翻别人程序,改了一下就过了。

    还有一个非常麻烦的事情是边界问题,程序里有一些需要打小于,有一些打小于等于,解决这个问题一种方法是对程序逻辑良好的整体把握,另一种方法是大力对拍,把可能情况测一遍就行了。

    样例太水,不要相信样例。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define LL  long long
    #define FILE "dealing"
    #define up(i,j,n) for(int i=j;i<=n;i++)
    LL read(){
    	LL x=0,f=1,ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	return x*f;
    }
    const LL maxn=800000,mod=1000000007,inf=10000000000000LL;
    bool cmin(LL& a,LL b){return a>b?a=b,true:false;}
    bool cmax(LL& a,LL b){return a<b?a=b,true:false;}
    LL n,m;
    struct node{LL x,y,op,ans,k,id;}a[maxn],q1[maxn],q2[maxn];
    bool cmp(node a,node b){return a.id<b.id;}
    LL key,left,right;
    LL delet[maxn],s[maxn],siz[maxn],flag[maxn];
    void add(LL x,LL del){delet[x]+=del,s[x]+=siz[x]*del;}
    void qing(LL x){delet[x]=s[x]=0;flag[x]=1;}
    void updata(LL x){s[x]=s[x<<1]+s[x<<1|1];}
    void pushdown(LL x){
    	if(flag[x])qing(x<<1),qing(x<<1|1),flag[x]=0;
    	if(delet[x])add(x<<1,delet[x]),add(x<<1|1,delet[x]),delet[x]=0;
    }
    void change(LL l,LL r,LL o){
    	if(l>right||r<left)return;
    	if(l>=left&&r<=right){add(o,key);return;}
    	LL mid=(l+r)>>1;
    	pushdown(o);
    	change(l,mid,o<<1);
    	change(mid+1,r,o<<1|1);
    	updata(o);
    }
    void Change(LL L,LL R,LL d){
    	left=L,right=R,key=d;
    	change(1,n,1);
    }
    LL query(LL l,LL r,LL o){
    	if(r<left||l>right)return 0;
    	if(l>=left&&r<=right)return s[o];
    	LL mid=(l+r)>>1;
    	pushdown(o);
    	return query(l,mid,o<<1)+query(mid+1,r,o<<1|1);
    }
    LL Query(LL L,LL R){
    	left=L,right=R;
    	return query(1,n,1);
    }
    void build(LL l,LL r,LL o){
    	if(l==r){siz[o]=1;return;}
    	LL mid=(l+r)>>1;
    	build(l,mid,o<<1);
    	build(mid+1,r,o<<1|1);
    	siz[o]=siz[o<<1]+siz[o<<1|1];
    }
    LL sum[maxn];
    void divide(LL L,LL R,LL l,LL r){
    	if(l>r)return;
    	if(L==R){
    		up(i,l,r)if(a[i].op==2)a[i].ans=L;
    		return;
    	}
    	qing(1);
    	LL mid=(L+R)>>1;
    	up(i,l,r){
    		if(a[i].op==1&&a[i].k>mid)Change(a[i].x,a[i].y,1);
    		else if(a[i].op==2)sum[i]=Query(a[i].x,a[i].y);
    	}
    	LL top1=0,top2=0;
    	up(i,l,r){
    		if(a[i].op==2){
    			if(sum[i]<=a[i].k){
    				a[i].k-=sum[i];
    				q1[++top1]=a[i];
    			}else q2[++top2]=a[i];
    		}
    		else {
    			if(a[i].k>mid)q2[++top2]=a[i];
    			else q1[++top1]=a[i];
    		}
    	}
    	up(i,l,l+top1-1)a[i]=q1[i-l+1];
    	up(i,l+top1,r)a[i]=q2[i-top1-l+1];
    	divide(L,mid,l,l+top1-1);
    	divide(mid+1,R,l+top1,r);
    }
    int main(){
    	freopen(FILE".in","r",stdin);
    	freopen(FILE".out","w",stdout);
    	n=read(),m=read();LL Min=inf,Max=-inf;
    	up(i,1,m){
    		a[i].op=read(),a[i].x=read(),a[i].y=read(),a[i].k=read();a[i].id=i;
    		if(a[i].op==2)a[i].k-=1;
    		if(a[i].op==1)cmin(Min,a[i].k),cmax(Max,a[i].k);
    	}
    	build(1,n,1);
    	divide(Min,Max,1,m);
    	sort(a+1,a+m+1,cmp);
    	up(i,1,m)if(a[i].op==2)printf("%lld
    ",a[i].ans);
    	return 0;
    }
    

      

  • 相关阅读:
    阿里云ssh断开处理办法
    OSSIM安装使用教程(OSSIM-5.6.5)
    MySQL字符串列与整数比较
    Linux获取so/ko文件版本号教程
    Linux服务器后门自动化查杀教程
    最强半自动化抓鸡工具打造思路
    渗透测试报告中的那些名词解释
    ELK+MySQL出现大量重复记录问题处理
    Python3+SQLAlchemy不使用字段名获取主键值教程
    Python3+SQLAlchemy+Sqlite3实现ORM教程
  • 原文地址:https://www.cnblogs.com/chadinblog/p/6439190.html
Copyright © 2011-2022 走看看