@IOU
2018-06-09T12:06:23.000000Z
字数 3108
阅读 1140
splay treap 主席树
可以去网盘里看。
【题目描述】
在 J 班的体育课上,同学们常常会迟到几分钟,但体育老师的点名却一直很
准时。老师只关心同学的身高,他会一次询问当前最高的身高,次高的身高,第
三高的身高,等等。在询问的过程中,会不时地有人插进队伍里。你需要回答老
师每次的询问。
【输入格式】
第一行两个整数 n,m,表示先后有 n 个人进队,老师询问了 m 次
第二行 n 个整数,第 i 个数 Ai 表示第 i 个进入队伍的同学的身高为 Ai
第三行 m 个整数,第 j 个数 Bj 表示老师在第 Bj 个同学进入队伍后有一次询问
【输出格式】
M 行,每行一个整数,依次表示老师每次询问的答案。数据保证合法
【样例输入】
7 4
9 7 2 8 14 1 8
1 2 6 6
【样例输出】
9
9
7
8
【样例解释】
(9){No.1=9};(9 7){No.2=9};(9 7 2 8 14 1){No.3=7;No.4=8}
【数据范围】
40%的数据保证 n≤1000
100%的数据保证 1≤m≤n≤30000;0≤Ai<2 32
数据结构题,由于数据范围很小。splay、treap、带修改主席树都可以做。
全当复习吧。。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#define maxn 300005#define lc ch[x][0]#define rc ch[x][1]#define ll long longusing namespace std;ll seq[maxn],ans[maxn],s[maxn];int cnt,ch[maxn][2],size[maxn],fa[maxn],r[maxn];struct que{int v,id;bool operator<(que x)const{return v<x.v;}}q[maxn];void maintain(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1;}void rotate(int &x,int d){int t=ch[x][d^1];ch[x][d^1]=ch[t][d];ch[t][d]=x;maintain(x);maintain(t);x=t;}ll query(int x,int k){if(size[lc]+1==k)return s[x];else if(size[lc]>=k)return query(lc,k);else return query(rc,k-1-size[lc]);}void insert(int &x,ll v,int f){if(x==0){x=++cnt,s[x]=v,size[x]=1;fa[x]=f;r[x]=rand()%99999999+1;return;}else if(s[x]>=v){insert(lc,v,x);if(r[lc]<r[x])rotate(x,1);}else {insert(rc,v,x);if(r[rc]<r[x])rotate(x,0);}maintain(x);}int main(){srand(time(NULL));//freopen("rollcall.in","r",stdin);//freopen("rollcall.out","w",stdout);int n,m;cin>>n>>m;for(int i=1;i<=n;i++)scanf("%lld",&seq[i]);for(int i=1;i<=m;i++)scanf("%d",&q[i].v),q[i].id=i;sort(q+1,q+1+m);int rt=1;int j=1;rt=++cnt;size[rt]=1;s[rt]=seq[1];for(int i=1;i<=m;i++){while(j<q[i].v){j++;insert(rt,seq[j],0);}ans[q[i].id]=query(rt,q[i].id);}for(int i=1;i<=m;i++)printf("%lld\n",ans[i]);return 0;}
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#define maxn 300005#define lc ch[x][0]#define rc ch[x][1]#define ll long longusing namespace std;ll seq[maxn],ans[maxn],s[maxn];int cnt,ch[maxn][2],size[maxn],fa[maxn],r[maxn],rt,tar;struct que{int v,id;bool operator<(que x)const{return v<x.v;}}q[maxn];void maintain(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1;}void rotate(int &x){int y=fa[x];int z=fa[y];int k=ch[y][1]==x;ch[z][ch[z][1]==y]=x;fa[x]=z;ch[y][k]=ch[x][k^1];fa[ch[x][k^1]]=y;ch[x][k^1]=y;fa[y]=x;maintain(y);maintain(z);maintain(x);}ll query(int x,int k){if(size[lc]+1==k)return s[x];else if(size[lc]>=k)return query(lc,k);else return query(rc,k-1-size[lc]);}void splay(int x,int goal){while(fa[x]!=goal){int y=fa[x],z=fa[y];if(z!=goal)(ch[z][0]==y)^(ch[y][0]==x)?rotate(x):rotate(y);rotate(x);}if(goal==0)rt=x;}void insert(int &x,ll v){if(x==0){x=++cnt,s[x]=v,size[x]=1;tar=x;return;}else if(s[x]>=v){insert(lc,v);fa[lc]=x;}else {insert(rc,v);fa[rc]=x;}maintain(x);}int main(){srand(time(NULL));//freopen("rollcall.in","r",stdin);//freopen("rollcall.out","w",stdout);int n,m;cin>>n>>m;for(int i=1;i<=n;i++)scanf("%lld",&seq[i]);for(int i=1;i<=m;i++)scanf("%d",&q[i].v),q[i].id=i;sort(q+1,q+1+m);int j=1;rt=++cnt;size[rt]=1;s[rt]=seq[1];for(int i=1;i<=m;i++){while(j<q[i].v){j++;insert(rt,seq[j]);splay(tar,rt);}ans[q[i].id]=query(rt,q[i].id);}for(int i=1;i<=m;i++)printf("%lld\n",ans[i]);return 0;}