[bzoj 3110--ZJOI2013]K大数查询
发布时间:2020-12-14 04:51:21 所属栏目:大数据 来源:网络整理
导读:有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。 MDZZ,这道题换了新数据后坑的一批,RE了我整整一版。这道题就是一
MDZZ,这道题换了新数据后坑的一批,RE了我整整一版。这道题就是一道整体二分裸题,但有一个加数操作,那就只要算它的贡献就可以了,具体看代码。本题有两个大坑点,第一个要用unsigned int,第二个在二分答案时,取mid在/2时要用位运算,不要单纯的/2,大坑点啊。 #include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#define ui unsigned int
using namespace std;
struct node
{
int l,r,id,d,k;
}q[51000],t1[51000],t2[51000];
int n,m;
struct trnode
{
int l,lc,rc,he;
ui c,lazy;
}tr[410000];ui trlen;
void bt(int l,int r)
{
trlen++;ui now=trlen;
tr[now].l=l;tr[now].r=r;
tr[now].lc=tr[now].rc=-1;
if(l<r)
{
int mid=(l+r)/2;
tr[now].lc=trlen+1;bt(l,mid);
tr[now].rc=trlen+1;bt(mid+1,r);
}
}
inline void update(int now)
{
int lc=tr[now].lc,rc=tr[now].rc;
if(lc==-1 && rc==-1)return ;
if(tr[now].he!=0)
{
tr[lc].c=tr[lc].lazy=tr[rc].c=tr[rc].lazy=0;
tr[lc].he=tr[rc].he=1;
tr[now].he=0;
}
if(tr[now].lazy!=0)
{
tr[lc].c+=(tr[lc].r-tr[lc].l+1)*tr[now].lazy;tr[lc].lazy+=tr[now].lazy;
tr[rc].c+=(tr[rc].r-tr[rc].l+1)*tr[now].lazy;tr[rc].lazy+=tr[now].lazy;
tr[now].lazy=0;
}
}
inline void change(int now,int l,int r)
{
if(tr[now].l==l && tr[now].r==r)
{
tr[now].c+=(ui)(tr[now].r-tr[now].l+1);
tr[now].lazy++;
return ;
}
if(tr[now].lazy!=0 || tr[now].he!=0)update(now);
int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;
if(r<=mid)change(lc,l,r);
else if(mid+1<=l)change(rc,r);
else change(lc,mid),change(rc,mid+1,r);
tr[now].c=tr[lc].c+tr[rc].c;
}
inline ui getsum(int now,int r)
{
if(tr[now].l==l && tr[now].r==r)return tr[now].c;
if(tr[now].lazy!=0 || tr[now].he!=0)update(now);
int lc=tr[now].lc,mid=(tr[now].l+tr[now].r)/2;
if(r<=mid)return getsum(lc,r);
else if(mid+1<=l)return getsum(rc,r);
else return (ui)getsum(lc,mid)+getsum(rc,r);
}
long long ans[51000];
void solve(int ll,int rr,int sl,int sr)
{
if(sl==sr)
{
for(int i=ll;i<=rr;i++)
{
if(q[i].id==2)ans[q[i].d]=sl;
}
return ;
}
int stl=0,str=0,mid=sl+sr>>1;//奇坑无比
tr[1].he=1;tr[1].c=tr[1].lazy=0;
for(int i=ll;i<=rr;i++)
{
if(q[i].id==2)
{
ui wy=getsum(1,q[i].l,q[i].r);
if(wy<(ui)q[i].k)
{
q[i].k-=wy;
t1[++stl]=q[i];
}
else t2[++str]=q[i];
}
else
{
if(q[i].k<=mid)t1[++stl]=q[i];
else change(1,q[i].r),t2[++str]=q[i];
}
}
int now=ll;
for(int i=1;i<=stl;i++)q[now++]=t1[i];
for(int i=1;i<=str;i++)q[now++]=t2[i];
if(stl!=0)solve(ll,ll+stl-1,sl,mid);
if(str!=0)solve(ll+stl,rr,sr);
}
int main()
{
int ss=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&q[i].id,&q[i].l,&q[i].r,&q[i].k);
if(q[i].id==2)q[i].d=++ss;
}
bt(1,n);solve(1,m,-n,n);
for(int i=1;i<=ss;i++)printf("%lldn",ans[i]);
return 0;
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |