这题用红黑树实现的可持久化数据结构可以很轻松的AC,码量非常小,自行百度。
MyCode:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;
typedef long long ll;
typedef unsigned long long ull;
struct node {
int lt,rt;
char s;
} t[maxn*10];
int tot,len[maxn],rt[maxn];
char ch,op;
void modify(int &x,int l,int r,int pos) {
t[++tot]=t[x];
x=tot;
if(l==r) return t[x].s=ch,void();
int mid=l+r>>1;
if(pos<=mid) modify(t[x].lt,l,mid,pos);
else modify(t[x].rt,mid+1,r,pos);
}
char query(int x,int l,int r,int pos) {
if(l==r) return t[x].s;
int mid=l+r>>1;
if(pos<=mid) return query(t[x].lt,l,mid,pos);
else return query(t[x].rt,mid+1,r,pos);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,cnt(0);
cin>>n;
for(int i=1,x; i<=n; ++i) {
cin>>op;
if(op=='T') {
++cnt;
cin>>ch;
len[cnt]=len[cnt-1]+1;
modify(rt[cnt]=rt[cnt-1],1,n,len[cnt]);
} else if(op=='U') {
cin>>x;
++cnt;
rt[cnt]=rt[cnt-x-1];
len[cnt]=len[cnt-x-1];
} else {
cin>>x;
cout<<query(rt[cnt],1,n,x)<<'\n';
}
}
return 0;
} 找中位数通过二分答案是第几大的数,然后判断一下。比二分值小的赋值为-1,大于等于二分值的赋值为1,因为如果n是偶数,这题中位数取的是中间偏大的那个数,所以判断答案是否可行的条件是最大连续区间和大于等于0 。其它的不多讲。主席树在这里的作用是,第i个版本维护的是升序中大的数赋值为-1、第
大的数赋值为1的线段树。
MyCode:
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn=2e4+11;
struct node{
int lt,rt,lm,s,rm;
}t[maxn*30];
int tot,n,ans,a[maxn],id[maxn],rt[maxn],q[4];
void pushup(int x,int l,int r) {
t[x].s=t[l].s+t[r].s;
t[x].lm=max(t[l].lm,t[l].s+t[r].lm);
t[x].rm=max(t[r].rm,t[r].s+t[l].rm);
}
void build(int &x,int l,int r) {
x=++tot;
if(l==r) return t[x].lm=t[x].s=t[x].rm=1,void();
int mid=(l+r)>>1;
build(t[x].lt,l,mid);
build(t[x].rt,mid+1,r);
pushup(x,t[x].lt,t[x].rt);
}
void modify(int &x,int l,int r,int p) {
t[++tot]=t[x];
x=tot;
if(l==r) return t[x].lm=t[x].s=t[x].rm=-1,void();
int mid=(l+r)>>1;
if(mid>=p) modify(t[x].lt,l,mid,p);
else modify(t[x].rt,mid+1,r,p);
pushup(x,t[x].lt,t[x].rt);
}
struct pd{
int s,lm,rm;
pd operator+(const pd &d)const {
return pd{s+d.s,max(lm,s+d.lm),max(d.rm,d.s+rm)};
}
};
int qs(int x,int l,int r,int lm,int rm) {
if(l<=lm&&rm<=r) return t[x].s;
int mid=(lm+rm)>>1;
if(l<=mid&&r>mid) return qs(t[x].lt,l,r,lm,mid)+qs(t[x].rt,l,r,mid+1,rm);
else if(l<=mid) return qs(t[x].lt,l,r,lm,mid);
else return qs(t[x].rt,l,r,mid+1,rm);
}
pd query(int x,int l,int r,int lm,int rm) {
if(l<=lm&&rm<=r) return pd{t[x].s,t[x].lm,t[x].rm};
int mid=(lm+rm)>>1;
if(l<=mid&&r>mid) return query(t[x].lt,l,r,lm,mid)+query(t[x].rt,l,r,mid+1,rm);
else if(l<=mid) return query(t[x].lt,l,r,lm,mid);
else return query(t[x].rt,l,r,mid+1,rm);
}
inline void solve() {
int A,B,C,D,sum,mid;
for(int i=0;i<4;++i) cin>>q[i];
q[0]=(q[0]+ans)%n+1;
q[1]=(q[1]+ans)%n+1;
q[2]=(q[2]+ans)%n+1;
q[3]=(q[3]+ans)%n+1;
sort(q,q+4);
A=q[0],B=q[1],C=q[2],D=q[3];
int l=1,r=n;
while(l<=r) {
mid=l+r>>1,sum=0;
if(B+1<=C-1) sum=qs(rt[mid],B+1,C-1,1,n);
sum+=query(rt[mid],A,B,1,n).rm+query(rt[mid],C,D,1,n).lm;
if(sum>=0) l=mid+1;
else r=mid-1;
}
ans=a[id[l-1]];
cout<<ans<<'\n';
}
bool cmp(int &x,int &y) {
return a[x]<a[y];
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>n;
for(int i=1;i<=n;++i) cin>>a[i],id[i]=i;
sort(id+1,id+1+n,cmp);
build(rt[1],1,n);
for(int i=2;i<=n;++i) modify(rt[i]=rt[i-1],1,n,id[i-1]);
int Q; cin>>Q; while(Q--) solve();
} 
京公网安备 11010502036488号