社区讨论
求助,改两天了
P3380【模板】树套树参与者 3已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @lo7uyrwp
- 此快照首次捕获于
- 2023/10/27 08:11 2 年前
- 此快照最后确认于
- 2023/10/27 08:11 2 年前
CPP
#include<iostream>
#include<cstring>
#define inf 2147483647
#define T tr[now]
#define FOR(i,x,y) for(int i(x);i<=y;++i)
using namespace std;
int a[50010];
struct node
{
int ls,rs;
int rnd;
int siz;
int val;
} tr[10000010];
int n,m;
int cnt;
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
inline int read()
{
char c=getchar();int x=0;bool f=0;
for(;!isdigit(c);c=getchar())f^=!(c^45);
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
if(f)x=-x;return x;
}
int x,y,z;
struct treap
{
int rt;
inline void pushup(int now)
{
T.siz=tr[T.ls].siz+tr[T.rs].siz+1;
return;
}
inline void split(int now,int k,int &x,int &y)
{
if(!now)x=y=0;
else
{
if(T.val<=k)x=now,split(T.rs,k,tr[x].rs,y);
else y=now,split(T.ls,k,x,tr[y].ls);
pushup(now);
}
return;
}
inline int merge(int A,int B)
{
if(!A||!B)return A+B;
else if(tr[A].rnd<tr[B].rnd)
{
tr[A].rs=merge(tr[A].rs,B);
pushup(A);
return A;
}
else
{
tr[B].ls=merge(A,tr[B].ls);
pushup(B);
return B;
}
}
inline int add(int now)
{
tr[++cnt].val=now;
tr[cnt].rnd=rand();
tr[cnt].siz=1;
return cnt;
}
inline void ins(int now)
{
int x,y;
split(rt,now,x,y);
rt=merge(merge(x,add(now)),y);
return;
}
inline void del(int now)
{
split(rt,now,x,z);
split(x,now-1,x,y);
y=merge(tr[y].ls,tr[y].rs);
rt=merge(merge(x,y),z);
return;
}
inline int rk(int now)
{
split(rt,now-1,x,y);
int res=tr[x].siz+1;
rt=merge(x,y);
return res;
}
inline int kth(int now,int k)
{
while(1)
{
if(!tr[now].siz)return 0;
else if(k<=tr[tr[now].ls].siz)
now=tr[now].ls;
else if(k==tr[tr[now].ls].siz+1)return tr[now].val;
else
{
k-=tr[tr[now].ls].siz+1;
now=tr[now].rs;
}
}
}
inline int pre(int now)
{
split(rt,now,x,y);
int res=kth(x,tr[x].siz);
if(!tr[x].siz)res=-inf;
rt=merge(x,y);
return res;
}
inline int nxt(int now)
{
split(rt,now-1,x,y);
int res=kth(y,1);
if(!tr[y].siz)res=inf;
rt=merge(x,y);
return res;
}
inline void build(int l, int r)
{
FOR(i,l,r)ins(a[i]);
return;
}
} ft[200001];
struct segmentree
{
inline void build(int x,int l,int r)
{
ft[x].build(l,r);
if(l==r)return;
int mid=l+r>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
}
inline int getrank(int x,int L,int R,int l,int r,int k)
{
if (R<l||L>r)return 0;
if (l<=L&&R<=r)return ft[x].rk(k)-1;
int mid=L+R>>1;
return getrank(x<<1,L,mid,l,r,k)+getrank(x<<1|1,mid+1,R,l,r,k);
}
inline int getk(int l,int r,int k)
{
int L=0,R=inf,ans=-1;
int mid;
while(L<=R)
{
mid=L+R>>1;
if(getrank(1,1,n,l,r,mid)+1<=k)ans=mid,L=mid+1;
else R=mid-1;
}
return ans;
}
inline void update(int x,int L,int R,int p,int k)
{
ft[x].del(a[p]);
ft[x].ins(k);
if(L==R)return;
int mid=L+R>>1;
if(p<=mid) update(x<<1,L,mid,p,k);
else update(x<<1|1,mid+1,R,p,k);
}
inline int getpre(int x,int L,int R,int l,int r,int k)
{
if (R<l||L>r)return -inf;
if (l<=L&&R<=r)return ft[x].pre(k);
int mid=L+R>>1;
return max(getpre(x<<1,L,mid,l,r,k),getpre(x<<1|1,mid+1,R,l,r,k));
}
inline int getnxt(int x,int L,int R,int l,int r,int k)
{
if (R<l||L>r)return inf;
if (l<=L&&R<=r)return ft[x].nxt(k);
int mid=L+R>>1;
return min(getnxt(x<<1,L,mid,l,r,k),getnxt(x<<1|1,mid+1,R,l,r,k));
}
} ST;
int main()
{
//freopen("tree.in","r",stdin);
//freopen("std.out","w",stdin);
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
srand(6666666);
n=read(),m=read();
FOR(i,1,n)a[i]=read();
ST.build(1,1,n);
int l,r,k,p;
FOR(i,1,m)
{
int opt;
opt=read();
if(opt==1)
{
l=read(),r=read(),k=read();
cout<<ST.getrank(1,1,n,l,r,k)+1<<endl;
}
else if(opt==2)
{
l=read(),r=read(),k=read();
cout<<ST.getk(l,r,k)<<endl;
}
else if(opt==3)
{
p=read(),k=read();
ST.update(1,1,n,p,k);
}
else if(opt==4)
{
l=read(),r=read(),k=read();
cout<<ST.getpre(1,1,n,l,r,k)<<endl;
}
else
{
l=read(),r=read(),k=read();
cout<<ST.getnxt(1,1,n,l,r,k)<<endl;
}
}
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...