题面
在 J 班的体育课上,同学们常常会迟到几分钟,但体育老师的点名却一直很准时。老师只关心同学的身高,他会依次询问当前最高的身高,次高的身高,第三高的身高,等等。在询问的过程中,会不时地有人插进队伍里。你需要回答老师每次的询问。第一行两个整数 n m,表示先后有 n 个人进队,老师询问了 m 次第二行 n 个整数,第 i 个数 Ai 表示第 i 个进入队伍的同学的身高为 Ai第三行 m 个整数,第 j 个数 Bj 表示老师在第 Bj 个同学进入队伍后询问第 j 高的人身高是多少。
40%的数据保证 n ≤ 1000
100%的数据保证 1 ≤ m ≤ n ≤ 30000; 0 ≤ Ai < 232
分析
数据真的太水了好吧
思路很多种,反正都是裸的数据结构。在此直接提供代码,本人写的对顶堆,值域线段树本来是首选,但是还要离散化,懒。
代码按一下顺序给,感激贡献代码的julao同学们
- 对顶堆
- 值域线段树
- 树状数组
可以当做各种模板题。。
代码
- #include<bits/stdc++.h>
- using namespace std;
- #define N 30030
- #define RT register
- #define ll long long
- ll n,m,k,in,cnt1,cnt2,ans;
- ll a[N];
- priority_queue<ll>q1;
- priority_queue<ll,vector<ll>,greater<ll> >q2;
- template<class T>
- inline void read(T &x)
- {
- x=0;ll f=1;static char ch=getchar();
- while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
- while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
- x*=f;
- }
- int main()
- {
- freopen("rollcall.in","r",stdin);
- freopen("rollcall.out","w",stdout);
- read(n),read(m);
- for(RT ll i=1;i<=n;i++)read(a[i]);in=1;
- for(RT ll i=1;i<=m;i++)
- {
- read(k);
- while(in<=k)
- {
- if(q1.empty()){q1.push(a[in]);cnt1++;in++;continue;}
- ll top=q1.top();
- if(a[in]>top)q2.push(a[in]),cnt2++;
- else q1.push(a[in]),cnt1++;
- in++;
- }
- while(!q2.empty()&&cnt1<i){ll tmp=q2.top();q2.pop();cnt2--;q1.push(tmp);cnt1++;}
- while(!q1.empty()&&cnt1>i){ll tmp=q1.top();q1.pop();cnt1--;q2.push(tmp);cnt2++;}
- ll top=q1.top();printf("%lld ",top);
- }
- return 0;
- }
- #include<cstdio>
- #include<cstring>
- #include<cstdlib>
- #include<algorithm>
- #include<map>
- using namespace std;
- #define re register int
- #define rec(i,j,k) for(re i=(j);i<=(k);i++)
- #define mem(s,k) memset(s,k,sizeof s)
- #define lson T[u].L,l,mid
- #define rson T[u].R,mid+1,r
- typedef long long LL;
- const int maxn=30000+1;
- LL a[maxn];
- struct fil
- {
- int num;
- LL val;
- }b[maxn];
- bool operator <(const fil &X,const fil &Y){return X.val<Y.val;}
- int root[maxn],non,rank[maxn],cnt,n,m;
- struct node
- {
- int sum,L,R;
- node(){sum=L=R=0;}
- }T[maxn*20];
- void updata(int &u,int l,int r,int k)
- {
- T[++non]=T[u];
- T[u=non].sum++;
- if(l==r)return;
- int mid=(l+r)>>1;
- if(k<=mid)updata(lson,k);
- else updata(rson,k);
- }
- int query(int L,int R,int l,int r,int k)
- {
- if(l==r)return l;
- int sum=T[T[R].L].sum-T[T[L].L].sum,mid=(l+r)>>1;
- if(k<=sum)return query(T[L].L,T[R].L,l,mid,k);
- else return query(T[L].R,T[R].R,mid+1,r,k-sum);
- }
- LL found(int k)
- {
- int l=1,r=n,mid;
- while(l<=r)
- {
- mid=(l+r)>>1;
- if(rank[b[mid].num]==k)return b[mid].val;
- if(rank[b[mid].num]<k)l=mid+1;
- else r=mid-1;
- }
- }
- int main()
- {
- scanf("%d%d",&n,&m);
- rec(i,1,n)
- {
- scanf("%lld",&a[i]);
- b[i]=(fil){i,a[i]};
- }
- sort(b+1,b+n+1);
- rank[b[1].num]=cnt=1;
- rec(i,1,n)
- if(b[i].val==b[i-1].val)rank[b[i].num]=cnt;
- else rank[b[i].num]=++cnt;
- rec(i,1,n)
- {
- root[i]=root[i-1];
- updata(root[i],1,cnt,rank[i]);
- }
- int k,t;
- rec(i,1,m)
- {
- scanf("%d",&k);
- t=query(root[0],root[k],1,cnt,i);
- printf("%lld ",found(t));
- }
- return 0;
- }
- #include <algorithm>
- #include <cstdio>
- using namespace std;
- typedef long long lint;
- const lint MAXN = 3e4 + 7;
- lint N,M;
- lint a[MAXN],b[MAXN];
- bool n[MAXN];
- lint c[MAXN]; //差分树状数组
- struct Query
- {
- lint p,q,ans;
- const bool operator <(const Query &a) const
- {
- return q < a.q;
- }
- }q[MAXN];
- inline lint lowbit(lint k) {return k & (-k);}
- inline void update(lint p,lint x)
- {
- for(lint i = p;i <= N;i += lowbit(i)) c[i] += x;
- }
- inline lint query(lint p)
- {
- lint ret = 0;
- for(lint i = p;i > 0;i -= lowbit(i)) ret += c[i];
- return ret;
- }
- inline void dump(lint x)
- {
- update(x,-1);
- }
- void binary_search(lint l,lint r,lint p)
- {
- while(n[l]) ++l;
- while(n[r]) --r;
- if(l > r) return;
- lint mid = (l + r) >> 1;
- while(n[mid]) ++mid;
- lint cmp = query(mid);
- if(cmp == q[p].q) {q[p].ans = b[mid];return;}
- else if(query(mid) > q[p].q) binary_search(l,mid - 1,p);
- else binary_search(mid + 1,r,p);
- }
- inline bool my_cmp(Query a,Query b) {return a.q < b.q;}
- int main()
- {
- scanf("%d %d",&N,&M);
- for(register lint i = 1;i <= N;i++)
- {
- scanf("%d",&a[i]);
- b[i] = a[i];
- }
- sort(b + 1,b + N + 1);
- for(register lint i = 1;i <= N;i++) c[i] = lowbit(i);
- for(register lint j = 1;j <= M;j++)
- {
- scanf("%d",&q[j].p);
- q[j].q = j;
- }
- sort(q + 1,q + M + 1);
- lint p = N;
- for(register lint i = M;i > 0;i--)
- {
- while(p > q[i].p)
- {
- lint cur = lower_bound(b + 1,b + N + 1,a[p]) - b;
- while(n[cur]) ++cur;
- n[cur] = true;
- dump(cur);
- p--;
- }
- binary_search(1,N,i);
- }
- sort(q + 1,q + M + 1,my_cmp);
- for(lint i = 1;i <= M;i++) printf("%lld ",q[i].ans);
- return 0;
- }