您的位置:首页 > 其它

bzoj3110[Zjoi2013]K大数查询

2017-02-24 16:43 369 查看
刚刚学习了整体二分,练习一下。

太长时间没写线段树了,结果在这道题里,线段树没有写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\n",a[i].ans);
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: