# [bzoj1901]动态区间k大

#include<iostream>
#include<cstdio>
#include<algorithm>
#define MN 2000000
#define MM 10000
using namespace std;
{
int x = 0 , f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
return x * f;
}
char op[5];
int rt[MM*2+5],n,m,cnt,tot,l2[MM*2+5],s[MM+5],c[1005],cnum,b[1005],bnum;
struct Segment_Tree{
int l,r,x;
}T[MN+5];
struct ques{
int kind,l,r,v;
}q[MM+5];

void ins(int x,int v,int ad,int l=1,int r=tot)
{
if(l==r) return;
int mid=l+r>>1;
}

{
for(;x<=tot;x+=x&(-x))
}

int main()
{
for(int i=1;i<=m;i++)
{
else q[i].kind=1,l2[++tot]=q[i].r;
}
sort(l2+1,l2+tot+1);
for(int i=1;i<=tot;i++) rt[i]=i;cnt=tot;
for(int i=1;i<=n;i++)
{
s[i]=lower_bound(l2+1,l2+tot+1,s[i])-l2;
renew(i,s[i],1);
}
for(int i=1;i<=m;i++)
{
if(q[i].kind==1)
{
q[i].r=lower_bound(l2+1,l2+tot+1,q[i].r)-l2;
renew(q[i].l,s[q[i].l],-1);
renew(q[i].l,q[i].r,1);
s[q[i].l]=q[i].r;
}
else
{
int l=1,r=tot,mid;cnum=bnum=0;
for(int j=q[i].r;j;j-=j&(-j))c[++cnum]=rt[j];
for(int j=q[i].l-1;j;j-=j&(-j)) b[++bnum]=rt[j];
while(l<=r)
{
mid=l+r>>1;int x=0;
for(int j=1;j<=cnum;j++) x+=T[T[c[j]].l].x;
for(int j=1;j<=bnum;j++) x-=T[T[b[j]].l].x;
if(x>=q[i].v)
{
r=mid;
for(int j=1;j<=cnum;j++) c[j]=T[c[j]].l;
for(int j=1;j<=bnum;j++) b[j]=T[b[j]].l;
}
else
{
l=mid+1;q[i].v-=x;
for(int j=1;j<=cnum;j++) c[j]=T[c[j]].r;
for(int j=1;j<=bnum;j++) b[j]=T[b[j]].r;
}
}
printf("%d\n",l2[r]);
}
}
return 0;
}

线段树套平衡树  结果我一不小心写成了树状数组  空间nlogn 时间nlog^3n

#include<iostream>
#include<cstdio>
#include<algorithm>
#define MN 400000
#define MM 10000
using namespace std;
{
int x = 0 , f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
return x * f;
}
char op[5];
int rt[MM*2+5],n,m,cnt,mark=0,tot,top=0,l2[MM*2+5],s[MM+5];
int c[MN+5][2],size[MN+5],num[MN+5],nn[MN+5],fa[MN+5],qx[MN+5];
struct ques{
int kind,l,r,v;
}q[MM+5];

{
if(!x){x=++cnt;nn[x]=v;num[x]=1;size[x]=1;fa[x]=last;return;}
size[x]=size[c[x][0]]+size[c[x][1]]+num[x];
if(max(size[c[x][0]],size[c[x][1]])>=0.7*size[x]) mark=x;
}

void dfs(int x)
{
if(c[x][0]) dfs(c[x][0]);
if(num[x])qx[++top]=x;
if(c[x][1]) dfs(c[x][1]);
fa[x]=c[x][0]=c[x][1]=0;
}

void build(int&x,int l,int r,int last)
{
if(l>r) {x=0;return;}int mid=l+r>>1;
x=qx[mid];fa[x]=last;
build(c[x][0],l,mid-1,x);
build(c[x][1],mid+1,r,x);
size[x]=size[c[x][0]]+size[c[x][1]]+num[x];
}

void rebuild(int i)
{
top=0;int y=fa[mark];dfs(mark);
if(!y) build(rt[i],1,top,0);
else build(c[y][c[y][1]==mark],1,top,y);
mark=0;
}

{
for(;x<=tot;x+=x&(-x))
{
if(mark) rebuild(x);
}
}

int query(int x,int k)
{
if(!x) return 0;
if(nn[x]>=k) return query(c[x][0],k)+((nn[x]==k)?num[x]:0);
else return size[c[x][0]]+num[x]+query(c[x][1],k);
}

int check(int x,int v)
{
int sum=0;
for(;x;x-=x&(-x))
sum+=query(rt[x],v);
return sum;
}

int main()
{
for(int i=1;i<=m;i++)
{
else q[i].kind=1,l2[++tot]=q[i].r;
}
sort(l2+1,l2+tot+1);
for(int i=1;i<=n;i++)
{
s[i]=lower_bound(l2+1,l2+tot+1,s[i])-l2;
renew(i,s[i],1);
}
for(int i=1;i<=m;i++)
{
if(q[i].kind==1)
{
q[i].r=lower_bound(l2+1,l2+tot+1,q[i].r)-l2;
renew(q[i].l,s[q[i].l],-1);
renew(q[i].l,q[i].r,1);
s[q[i].l]=q[i].r;
}
else
{
int l=1,r=tot,mid,ans=0;
while(l<=r)
{
mid=l+r>>1;
int x=check(q[i].r,mid)-check(q[i].l-1,mid);
//cout<<l2[mid]<<" "<<check(q[i].r,mid)<<" "<<check(q[i].l-1,mid)<<endl;
if(x>=q[i].v) ans=mid,r=mid-1;
else l=mid+1;
}
printf("%d\n",l2[ans]);
}
}
return 0;
}

posted @ 2017-03-22 15:42  FallDream  阅读(466)  评论(0编辑  收藏