记录编号 414335 评测结果 AAAAAAAAAA
题目名称 [NEERC 2004] K小数 最终得分 100
用户昵称 GravatarHzoi_Ivan 是否通过 通过
代码语言 C++ 运行时间 0.008 s
提交时间 2017-06-14 07:39:40 内存使用 6.01 MiB
显示代码纯文本
  1. //主席树,权值线段树,每个线段存的是这个区间大小的数当前出现的次数
  2. #include<cstdio>
  3. #include<algorithm>
  4. #define N 100005
  5. using namespace std;
  6. int a[N],num[N],n,m,cnt=0,root[N];
  7. int ql,qr,k;
  8. struct Tree
  9. {
  10. int l,r,sum;
  11. }tree[N*4];
  12. void build(int &o,int l,int r)
  13. {
  14. o=++cnt;
  15. tree[o].sum=0;
  16. if(l==r) return ;
  17. int m=(l+r)/2;
  18. build(tree[o].l,l,m);
  19. build(tree[o].r,m+1,r);
  20. }
  21. void update(int p,int &o,int l,int r,int x)
  22. {
  23. o=++cnt;
  24. tree[o]=tree[p];
  25. tree[o].sum++;
  26. if(l==r) return ;
  27. int m=(l+r)/2;
  28. if(x<=m)
  29. update(tree[p].l,tree[o].l,l,m,x);
  30. else
  31. update(tree[p].r,tree[o].r,m+1,r,x);
  32. }
  33. int query(int p,int o,int l,int r,int x)
  34. {
  35. if(l==r) return l;
  36. int m=(l+r)/2;
  37. int ln=tree[tree[o].l].sum-tree[tree[p].l].sum;
  38. if(x<=ln) return query(tree[p].l,tree[o].l,l,m,x);
  39. else return query(tree[p].r,tree[o].r,m+1,r,x-ln);
  40. }
  41. int main()
  42. {
  43. freopen("kthnumber.in","r",stdin);
  44. freopen("kthnumber.out","w",stdout);
  45. scanf("%d%d",&n,&m);
  46. for(int i=1;i<=n;i++){
  47. scanf("%d",&a[i]);
  48. num[i]=a[i];
  49. }
  50. sort(num+1,num+n+1);
  51. int num_cnt=unique(num+1,num+n+1)-num-1; //去重
  52. build(root[0],1,num_cnt); //建空树
  53. //for(int i=1;i<=num_cnt;i++)
  54. //printf("%d ",num[i]);
  55. //printf("\n");
  56. for(int i=1;i<=n;i++)
  57. {
  58. int x=lower_bound(num+1,num+num_cnt+1,a[i])-num; //离散
  59. //printf("%d %d\n",a[i],x);
  60. update(root[i-1],root[i],1,num_cnt,x);
  61. }
  62. for(int i=1;i<=m;i++)
  63. {
  64. scanf("%d%d%d",&ql,&qr,&k);
  65. int x=query(root[ql-1],root[qr],1,num_cnt,k);
  66. printf("%d\n",num[x]);
  67. }
  68. //while(1);
  69. }