社区讨论
神秘树套树玄关求调
P3380【模板】树套树参与者 1已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mizyfdgl
- 此快照首次捕获于
- 2025/12/10 19:57 3 个月前
- 此快照最后确认于
- 2025/12/13 10:15 3 个月前
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e4+10;
const int inf=2147483647;
inline int read() {
int x=0,f=0;
char c=getchar();
while(!isdigit(c)) {
f|=c=='-';
c=getchar();
}
while(isdigit(c)) {
x=x*10+c-48;
c=getchar();
}
return f?-x:x;
}
struct qst {
int op,l,r,x;
} q[N];
inline int lb(int x) {
return x&-x;
}
int a[N<<5],n,m,len,lsh[N<<4],rooot[N<<2];
int tot=0,num=0,cnt=0;
int tmp[N<<5],tem[N<<5];
struct tree {
struct nod {
int v,ls,rs;
} w[N<<5];
int add(int u) {
w[++tot]=w[u];
return tot;
}
void psh(int u) {
w[u].v=w[w[u].ls].v+w[w[u].rs].v;
}
int chg(int u,int l,int r,int k,int x) {
if(!u)u=add(u);
if(l==r) {
w[u].v=x;
return u;
}
int mid=(l+r)>>1;
if(k<=mid)w[u].ls=chg(w[u].ls,l,mid,k,x);
else w[u].rs=chg(w[u].rs,mid+1,r,k,x);
psh(u);
return u;
}
int qry(int l,int r,int k) {
if(l==r) {
return l;
}
int mid=(l+r)>>1;
int sum=0;
for(int i=1; i<=cnt; i++)sum+=w[w[tem[i]].ls].v;
for(int i=1; i<=num; i++)sum-=w[w[tmp[i]].ls].v;
if(k<=sum) {
for(int i=1; i<=cnt; i++)tem[i]=w[tem[i]].ls;
for(int i=1; i<=num; i++)tmp[i]=w[tmp[i]].ls;
return qry(l,mid,k);
} else {
for(int i=1; i<=cnt; i++)tem[i]=w[tem[i]].rs;
for(int i=1; i<=num; i++)tmp[i]=w[tmp[i]].rs;
return qry(mid+1,r,k-sum);
}
}
int qry_rk(int l,int r,int k) {
if(l==r) {
return 0;
}
int mid=(l+r)>>1;
int sum=0;
if(k<=mid) {
for(int i=1; i<=cnt; i++)tem[i]=w[tem[i]].ls;
for(int i=1; i<=num; i++)tmp[i]=w[tmp[i]].ls;
return qry(l,mid,k);
} else {
for(int i=1; i<=cnt; i++)sum+=w[w[tem[i]].ls].v,tem[i]=w[tem[i]].rs;
for(int i=1; i<=num; i++)sum-=w[w[tmp[i]].ls].v,tmp[i]=w[tmp[i]].rs;
return sum+qry(mid+1,r,k);
}
}
} seg;
struct Node {
void Add(int u,int x) {
for(int i=u; i<=n; i+=lb(i)) {
rooot[i]=seg.chg(rooot[i],1,len,a[u],x);
}
}
int fid_num(int l,int r,int k) {
num=cnt=0;
for(int i=r; i; i-=lb(i)) {
tem[++cnt]=rooot[i];
}
for(int i=l-1; i; i-=lb(i)) {
tmp[++num]=rooot[i];
}
return seg.qry(1,len,k);
}
int fid_rk(int l,int r,int k) {
num=cnt=0;
for(int i=r; i; i-=lb(i)) {
tem[++cnt]=rooot[i];
}
for(int i=l-1; i; i-=lb(i)) {
tmp[++num]=rooot[i];
}
return seg.qry_rk(1,len,k)+1;
}
int fid_pre(int l,int r,int k) {
int rk=fid_rk(l,r,k)-1;
if(rk==0)return 0;
return fid_num(l,r,rk);
}
int fid_bck(int l,int r,int k) {
if(k==len)return len+1;
int rk=fid_rk(l,r,k+1);
if(rk==r-l+2)return len+1;
return fid_num(l,r,rk);
}
} tre;
signed main() {
n=read(),m=read();
for(int i=1; i<=n; i++) {
lsh[++len]=a[i]=read();
}
for(int i=1; i<=m; i++) {
q[i].op=read();
q[i].l=read();
q[i].r=read();
if(q[i].op!=3) q[i].x=read();
else lsh[++len]=q[i].r;
if(q[i].op==4 || q[i].op==5) lsh[++len]=q[i].x;
}
sort(lsh+1,lsh+1+len);
len=unique(lsh+1,lsh+1+len)-lsh-1;
lsh[0]=-inf,lsh[len+1]=inf;
for(int i=1; i<=n; i++) {
a[i]=lower_bound(lsh+1,lsh+1+len,a[i])-lsh;
tre.Add(i,1);
}
for(int i=1; i<=m; i++) {
if(q[i].op==3) {
tre.Add(q[i].l,-1);
a[q[i].l]=lower_bound(lsh+1,lsh+1+len,q[i].r)-lsh;
tre.Add(q[i].l,1);
}
if(q[i].op==1) {
q[i].x=lower_bound(lsh+1,lsh+1+len,q[i].x)-lsh;
printf("%lld\n",tre.fid_rk(q[i].l,q[i].r,q[i].x));
}
if(q[i].op==2) {
printf("%lld\n",lsh[tre.fid_num(q[i].l,q[i].r,q[i].x)]);
}
if(q[i].op==4) {
printf("%lld\n",lsh[tre.fid_pre(q[i].l,q[i].r,lower_bound(lsh+1,lsh+1+len,q[i].x)-lsh)]);
}
if(q[i].op==5) {
printf("%lld\n",lsh[tre.fid_bck(q[i].l,q[i].r,lower_bound(lsh+1,lsh+1+len,q[i].x)-lsh)]);
}
}
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...