【NOIP模拟】点名

题面

在 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同学们

  1. 对顶堆
  2. 值域线段树
  3. 树状数组

可以当做各种模板题。。

代码

  1. #include<bits/stdc++.h>  
  2. using namespace std;  
  3. #define N 30030  
  4. #define RT register  
  5. #define ll long long  
  6. ll n,m,k,in,cnt1,cnt2,ans;  
  7. ll a[N];  
  8. priority_queue<ll>q1;  
  9. priority_queue<ll,vector<ll>,greater<ll> >q2;   
  10. template<class T>  
  11. inline void read(T &x)  
  12. {  
  13.     x=0;ll f=1;static char ch=getchar();  
  14.     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}  
  15.     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}  
  16.     x*=f;  
  17. }  
  18. int main()  
  19. {  
  20.     freopen("rollcall.in","r",stdin);  
  21.     freopen("rollcall.out","w",stdout);  
  22.     read(n),read(m);  
  23.     for(RT ll i=1;i<=n;i++)read(a[i]);in=1;  
  24.     for(RT ll i=1;i<=m;i++)  
  25.     {  
  26.         read(k);  
  27.         while(in<=k)  
  28.         {  
  29.             if(q1.empty()){q1.push(a[in]);cnt1++;in++;continue;}  
  30.             ll top=q1.top();  
  31.             if(a[in]>top)q2.push(a[in]),cnt2++;  
  32.             else q1.push(a[in]),cnt1++;   
  33.             in++;     
  34.         }  
  35.         while(!q2.empty()&&cnt1<i){ll tmp=q2.top();q2.pop();cnt2--;q1.push(tmp);cnt1++;}  
  36.         while(!q1.empty()&&cnt1>i){ll tmp=q1.top();q1.pop();cnt1--;q2.push(tmp);cnt2++;}  
  37.         ll top=q1.top();printf("%lld\n",top);   
  38.     }  
  39.     return 0;  
  40. }   

 

 
  1. #include<cstdio>  
  2. #include<cstring>  
  3. #include<cstdlib>  
  4. #include<algorithm>  
  5. #include<map>  
  6. using namespace std;  
  7. #define re register int  
  8. #define rec(i,j,k) for(re i=(j);i<=(k);i++)  
  9. #define mem(s,k) memset(s,k,sizeof s)  
  10. #define lson T[u].L,l,mid  
  11. #define rson T[u].R,mid+1,r  
  12. typedef long long LL;  
  13. const int maxn=30000+1;  
  14. LL a[maxn];  
  15. struct fil  
  16. {  
  17.     int num;  
  18.     LL val;  
  19. }b[maxn];  
  20. bool operator <(const fil &X,const fil &Y){return X.val<Y.val;}  
  21. int root[maxn],non,rank[maxn],cnt,n,m;  
  22. struct node  
  23. {  
  24.     int sum,L,R;  
  25.     node(){sum=L=R=0;}  
  26. }T[maxn*20];  
  27. void updata(int &u,int l,int r,int k)  
  28. {  
  29.     T[++non]=T[u];  
  30.     T[u=non].sum++;  
  31.     if(l==r)return;  
  32.     int mid=(l+r)>>1;  
  33.     if(k<=mid)updata(lson,k);  
  34.     else updata(rson,k);  
  35. }  
  36. int query(int L,int R,int l,int r,int k)  
  37. {  
  38.     if(l==r)return l;  
  39.     int sum=T[T[R].L].sum-T[T[L].L].sum,mid=(l+r)>>1;  
  40.     if(k<=sum)return query(T[L].L,T[R].L,l,mid,k);  
  41.     else return query(T[L].R,T[R].R,mid+1,r,k-sum);  
  42. }  
  43. LL found(int k)  
  44. {  
  45.     int l=1,r=n,mid;  
  46.     while(l<=r)  
  47.     {  
  48.         mid=(l+r)>>1;  
  49.         if(rank[b[mid].num]==k)return b[mid].val;  
  50.         if(rank[b[mid].num]<k)l=mid+1;  
  51.         else r=mid-1;  
  52.     }  
  53. }  
  54. int main()  
  55. {  
  56.   
  57.     scanf("%d%d",&n,&m);  
  58.     rec(i,1,n)  
  59.     {  
  60.      scanf("%lld",&a[i]);  
  61.      b[i]=(fil){i,a[i]};  
  62.     }  
  63.     sort(b+1,b+n+1);  
  64.     rank[b[1].num]=cnt=1;  
  65.     rec(i,1,n)  
  66.      if(b[i].val==b[i-1].val)rank[b[i].num]=cnt;  
  67.      else rank[b[i].num]=++cnt;  
  68.     rec(i,1,n)  
  69.     {  
  70.         root[i]=root[i-1];  
  71.         updata(root[i],1,cnt,rank[i]);  
  72.     }  
  73.     int k,t;  
  74.     rec(i,1,m)  
  75.     {  
  76.         scanf("%d",&k);  
  77.         t=query(root[0],root[k],1,cnt,i);  
  78.         printf("%lld\n",found(t));  
  79.     }  
  80.     return 0;  
  81. }  

 

 
  1. #include <algorithm>  
  2. #include <cstdio>  
  3. using namespace std;  
  4.   
  5. typedef long long lint;  
  6. const lint MAXN = 3e4 + 7;  
  7. lint N,M;  
  8. lint a[MAXN],b[MAXN];  
  9. bool n[MAXN];  
  10. lint c[MAXN];  //差分树状数组   
  11. struct Query  
  12. {  
  13.     lint p,q,ans;  
  14.     const bool operator <(const Query &a)  const  
  15.     {  
  16.         return q < a.q;  
  17.     }  
  18. }q[MAXN];  
  19.   
  20. inline lint lowbit(lint k)  {return k & (-k);}  
  21.   
  22. inline void update(lint p,lint x)  
  23. {  
  24.     for(lint i = p;i <= N;i += lowbit(i))  c[i] += x;  
  25. }  
  26.   
  27. inline lint query(lint p)  
  28. {  
  29.     lint ret = 0;  
  30.     for(lint i = p;i > 0;i -= lowbit(i))  ret += c[i];  
  31.     return ret;  
  32. }  
  33.   
  34. inline void dump(lint x)  
  35. {  
  36.     update(x,-1);  
  37. }  
  38.   
  39. void binary_search(lint l,lint r,lint p)  
  40. {  
  41.     while(n[l])  ++l;  
  42.     while(n[r])  --r;  
  43.     if(l > r)  return;  
  44.     lint mid = (l + r) >> 1;  
  45.     while(n[mid])  ++mid;  
  46.     lint cmp = query(mid);  
  47.     if(cmp == q[p].q)  {q[p].ans = b[mid];return;}  
  48.     else if(query(mid) > q[p].q)  binary_search(l,mid - 1,p);  
  49.     else binary_search(mid + 1,r,p);  
  50. }  
  51.   
  52. inline bool my_cmp(Query a,Query b)  {return a.q < b.q;}  
  53.   
  54. int main()  
  55. {  
  56.     scanf("%d %d",&N,&M);  
  57.     for(register lint i = 1;i <= N;i++)  
  58.     {  
  59.         scanf("%d",&a[i]);  
  60.         b[i] = a[i];  
  61.     }  
  62.     sort(b + 1,b + N + 1);  
  63.     for(register lint i = 1;i <= N;i++)  c[i] = lowbit(i);  
  64.     for(register lint j = 1;j <= M;j++)  
  65.     {  
  66.         scanf("%d",&q[j].p);  
  67.         q[j].q = j;  
  68.     }  
  69.     sort(q + 1,q + M + 1);  
  70.     lint p = N;  
  71.     for(register lint i = M;i > 0;i--)  
  72.     {  
  73.         while(p > q[i].p)    
  74.         {  
  75.             lint cur = lower_bound(b + 1,b + N + 1,a[p]) - b;  
  76.             while(n[cur])  ++cur;  
  77.             n[cur] = true;  
  78.             dump(cur);  
  79.             p--;  
  80.         }  
  81.           
  82.         binary_search(1,N,i);  
  83.     }  
  84.     sort(q + 1,q + M + 1,my_cmp);  
  85.     for(lint i = 1;i <= M;i++)  printf("%lld\n",q[i].ans);  
  86.     return 0;  
  87. }  
  88.      
posted @ 2018-10-27 16:54  WJEMail  阅读(281)  评论(0编辑  收藏  举报