您的位置:首页 > 其它

bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树

2014-11-13 22:03 525 查看

3110: [Zjoi2013]K大数查询

Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 1384 Solved: 629
[Submit][Status]

Description

有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c
如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。

Input

第一行N,M
接下来M行,每行形如1 a b c或2 a b c

Output

输出每个询问的结果

Sample Input

2 5

1 1 2 1

1 1 2 2

2 1 1 2

2 1 1 1

2 1 2 3

Sample Output

1

2

1

HINT

【样例说明】

第一个操作 后位置 1 的数只有 1 , 位置 2 的数也只有 1 。 第二个操作 后位置 1

的数有 1 、 2 ,位置 2 的数也有 1 、 2 。 第三次询问 位置 1 到位置 1 第 2 大的数 是

1 。 第四次询问 位置 1 到位置 1 第 1 大的数是 2 。 第五次询问 位置 1 到位置 2 第 3

大的数是 1 。‍

N,M<=50000,N,M<=50000

a<=b<=N

1操作中abs(c)<=N

2操作中abs(c)<=Maxlongint

  这道题本来想用线段树套平衡树做,但是即便加了永久lazy标记,还是TLE了,后来改为树状数组套线段树,注意树状数组二分可优化为O(logn)

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 101000
#define MAXT 28000000
#define lowbit(x) (x&(-x))
inline int nextInt()
{
register int x=0;
register char ch;
while (ch=(char)getchar(),ch<'0'||ch > '9');
do
x=x*10+ch-'0';
while (ch=(char)getchar(),ch<='9' && ch>='0');
return x;
}

int n,m;
struct sgt_node
{
int lch,rch;
int t,lazy;
}sgt[MAXT];
int topt=0;
void Add_sgt(int &now,int l,int r,int x,int y)
{
if (!now)
{
now=++topt;
sgt[now].t=sgt[now].lazy=0;
}
if (l==x && r==y)
{
sgt[now].t+=r-l+1;
sgt[now].lazy++;
return ;
}
int mid=(l+r)>>1;
if (sgt[now].lazy)
{
if (!sgt[now].lch)
sgt[now].lch=++topt;
if (!sgt[now].rch)
sgt[now].rch=++topt;
sgt[sgt[now].lch].lazy+=sgt[now].lazy;
sgt[sgt[now].rch].lazy+=sgt[now].lazy;
sgt[sgt[now].lch].t+=sgt[now].lazy*(mid-l+1);
sgt[sgt[now].rch].t+=sgt[now].lazy*(r-mid);
sgt[now].lazy=0;
}
if (y<=mid)
{
Add_sgt(sgt[now].lch,l,mid,x,y);
}else if (mid<x)
{
Add_sgt(sgt[now].rch,mid+1,r,x,y);
}else
{
Add_sgt(sgt[now].lch,l,mid,x,mid);
Add_sgt(sgt[now].rch,mid+1,r,mid+1,y);
}
sgt[now].t=sgt[sgt[now].lch].t+sgt[sgt[now].rch].t;
}
int Qry_sgt(int &now,int l,int r,int x,int y)
{
if (!now || sgt[now].t==0)return 0;
if (l==x && r==y)
return sgt[now].t;
int mid=(l+r)>>1;
if (sgt[now].lazy)
{
if (!sgt[now].lch)
sgt[now].lch=++topt;
if (!sgt[now].rch)
sgt[now].rch=++topt;
sgt[sgt[now].lch].lazy+=sgt[now].lazy;
sgt[sgt[now].rch].lazy+=sgt[now].lazy;
sgt[sgt[now].lch].t+=sgt[now].lazy*(mid-l+1);
sgt[sgt[now].rch].t+=sgt[now].lazy*(r-mid);
sgt[now].lazy=0;
}
if (y<=mid)
{
return Qry_sgt(sgt[now].lch,l,mid,x,y);
}else if (mid<x)
{
return Qry_sgt(sgt[now].rch,mid+1,r,x,y);
}else
{
return Qry_sgt(sgt[now].lch,l,mid,x,mid)
+Qry_sgt(sgt[now].rch,mid+1,r,mid+1,y);
}
}
int tarr2[MAXN],tarr3[MAXN];
void Add_tarr2(int l,int r)
{
r++;
int a=r;
while (r<MAXN)
{
tarr2[r]--;
tarr3[r]-=a;
r+=lowbit(r);
}
a=l;
while (l<MAXN)
{
tarr2[l]++;
tarr3[l]+=a;
l+=lowbit(l);
}
}
//segma((n-i+1)*a[i])
//=(n+1)*segma(a[i]) - segma(i*a[i])
int Qry_tarr2(int l,int r)
{
int ret=0;
int v1,v2;
int now;
v1=0;
l--;
now=r;
v1=v2=0;
while (now)
{
v1+=tarr2[now];
v2+=tarr3[now];
now-=lowbit(now);
}
ret+=v1*(r+1)-v2;
now=l;
v1=v2=0;
while (now)
{
v1+=tarr2[now];
v2+=tarr3[now];
now-=lowbit(now);
}
ret-=v1*(l+1)-v2;
return ret;
}
int tarr[MAXN];
void Add_tarr(int pos,int l,int r)
{
pos+=n+1;
Add_tarr2(l,r);
while (pos<MAXN)
{
Add_sgt(tarr[pos],0,n+1,l,r);
pos+=lowbit(pos);
}
}
/*
int Qry_tarr(int rk,int ll,int rr)
{
int now=0,t;
int i;
int l,r,mid;
rk=Qry_tarr2(ll,rr)-rk+1;
l=-n-1;r=n+1;
while (l+1<r)
{
t=0;
mid=(l+r)>>1;
now=mid+n+1;
while (now)
{
t+=Qry_sgt(tarr[now],0,n+1,ll,rr);
now-=lowbit(now);
}
if (t<rk)
l=mid;
else
r=mid;
}
return r==-n ? 1 : r;
}*/
int Qry_tarr(int rk,int ll,int rr)
{
int now=0,t;
int i;
int l,r,mid;
rk=Qry_tarr2(ll,rr)-rk+1;
for (i=20;i>=0;i--)
{
if (now+(1<<i)<MAXN && (t=Qry_sgt(tarr[now+(1<<i)],0,n+1,ll,rr))<rk)
{
rk-=t;
now+=(1<<i);
}
}
now=now+1-(n+1);
return now;
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d%d",&n,&m);
int i;
int opt,x,y,z;
for (i=0;i<m;i++)
{
opt=nextInt();
x=nextInt();
y=nextInt();
z=nextInt();
//scanf("%d%d%d%d",&opt,&x,&y,&z);
if (opt==1)
{
Add_tarr(z,x,y);
}else
{
printf("%d\n",Qry_tarr(z,x,y));
}
}
}


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