WZJ的数据结构(十三)
难度级别:D; 运行时间限制:1000ms; 运行空间限制:262144KB; 代码长度限制:2000000B
试题描述

给你一棵N个节点的有根树(根节点为1),每个节点有权值Vi。请回答Q个问题:

每次给你两个正整数x、k,请回答以x为根的子树(包括x节点)中第k小的权值是多少(若不存在第k小数,输出-1)?

输入
第一行为两个正整数N,Q。
接下来N-1行每行两个正整数ui、vi,表示有条从ui向vi的树边。
第N+1行为N个正整数Vi。
最后Q行每行两个正整数x、k。
输出
对于每次询问输出答案,若不存在第k小数,输出-1。
输入示例
6 12
1 2
1 3
2 4
3 6
3 5
1 2 1 3 2 1
1 5
2 2
3 4
1 1
1 2
1 3
1 4
1 6
3 3
3 2
5 1
6 1
输出示例
2
3
-1
1
1
1
2
3
2
1
2
1
其他说明
1<=N,M,Vi<=100000
1<=x,k<=N

新学了线段树的合并,来try一发。

  1. #include<cstdio>
  2. #include<cctype>
  3. #include<queue>
  4. #include<cmath>
  5. #include<cstring>
  6. #include<algorithm>
  7. #define rep(i,s,t) for(int i=s;i<=t;i++)
  8. #define dwn(i,s,t) for(int i=s;i>=t;i--)
  9. #define ren for(int i=first[x];i;i=next[i])
  10. using namespace std;
  11. inline int read() {
  12. int x=,f=;char c=getchar();
  13. for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
  14. for(;isdigit(c);c=getchar()) x=x*+c-'';
  15. return x*f;
  16. }
  17. const int maxn=;
  18. const int maxnode=;
  19. int first[maxn],next[maxn<<],to[maxn<<],last[maxn],n,q,e,cnt;
  20. void AddEdge(int u,int v) {
  21. to[++e]=v;next[e]=first[u];first[u]=e;
  22. to[++e]=u;next[e]=first[v];first[v]=e;
  23. }
  24. int ls[maxnode],rs[maxnode],sumv[maxnode],ToT;
  25. void update(int& x,int l,int r,int pos) {
  26. sumv[x=++ToT]=;if(l==r) return;
  27. int mid=l+r>>;
  28. if(pos<=mid) update(ls[x],l,mid,pos);
  29. else update(rs[x],mid+,r,pos);
  30. }
  31. int merge(int x,int y) {
  32. if(!x||!y) return max(x,y);
  33. if(!ls[x]&&!rs[x]) sumv[x]+=sumv[y];
  34. else {
  35. ls[x]=merge(ls[x],ls[y]);rs[x]=merge(rs[x],rs[y]);
  36. sumv[x]=sumv[ls[x]]+sumv[rs[x]];
  37. }
  38. return x;
  39. }
  40. int query(int x,int l,int r,int k) {
  41. if(sumv[x]<k) return -;
  42. if(l==r) return l;
  43. int mid=l+r>>,k2=sumv[ls[x]];
  44. if(k2>=k) return query(ls[x],l,mid,k);
  45. return query(rs[x],mid+,r,k-k2);
  46. }
  47. struct Query {
  48. int k,next,id;
  49. }Q[maxn];
  50. int ans[maxn],root[maxn],val[maxn];
  51. void AddQuery(int k,int x,int id) {
  52. Q[++cnt]=(Query){k,last[x],id};last[x]=cnt;
  53. }
  54. void dfs(int x,int fa) {
  55. update(root[x],,,val[x]);
  56. ren if(to[i]!=fa) {
  57. dfs(to[i],x);
  58. root[x]=merge(root[x],root[to[i]]);
  59. }
  60. for(int i=last[x];i;i=Q[i].next) ans[Q[i].id]=query(root[x],,,Q[i].k);
  61. }
  62. int main() {
  63. n=read();q=read();
  64. rep(i,,n) AddEdge(read(),read());
  65. rep(i,,n) val[i]=read();
  66. rep(i,,q) AddQuery(read(),read(),i);
  67. dfs(,);
  68. rep(i,,q) printf("%d\n",ans[i]);
  69. return ;
  70. }

之前的平衡树启发式合并。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<queue>
  4. #include<cstdlib>
  5. #include<ctime>
  6. #include<algorithm>
  7. using namespace std;
  8. const int maxn=;
  9. struct Node
  10. {
  11. int r,s,v;
  12. Node* ch[];
  13. void maintain()
  14. {
  15. s=ch[]->s+ch[]->s+;
  16. }
  17. }*null=new Node(),nodes[maxn*];
  18. int tot;
  19. queue<Node*> Q;
  20. Node* node()
  21. {
  22. if(!Q.empty())
  23. {
  24. Node* o=Q.front(); Q.pop();
  25. return o;
  26. }
  27. return &nodes[tot++];
  28. }
  29. void del(Node* &o)
  30. {
  31. Q.push(o);
  32. o=null;
  33. }
  34. void rotate(Node* &o,int d)
  35. {
  36. Node* k=o->ch[d^]; o->ch[d^]=k->ch[d]; k->ch[d]=o;
  37. o->maintain(); k->maintain(); o=k;
  38. }
  39. void insert(Node* &o,int v)
  40. {
  41. if(o==null)
  42. {
  43. o=node();
  44. o->ch[]=o->ch[]=null;
  45. o->r=rand();
  46. o->s=;
  47. o->v=v;
  48. }
  49. else
  50. {
  51. int d=v>o->v;
  52. insert(o->ch[d],v);
  53. if(o->ch[d]->r>o->r) rotate(o,d^);
  54. else o->maintain();
  55. }
  56. }
  57. void remove(Node* &o,int v)
  58. {
  59. if(v==o->v)
  60. {
  61. if(o->ch[]!=null&&o->ch[]!=null)
  62. {
  63. int d=o->ch[]->r>o->ch[]->r;
  64. rotate(o,d); remove(o->ch[d],v);
  65. }
  66. else
  67. {
  68. Node* k=o;
  69. if(o->ch[]!=null) o=o->ch[];
  70. else o=o->ch[];
  71. del(k);
  72. }
  73. }
  74. else remove(o->ch[v>o->v],v);
  75. }
  76. int query(Node* &o,int k)
  77. {
  78. if(k>o->s) return -;
  79. if(k==o->ch[]->s+) return o->v;
  80. if(k<=o->ch[]->s) return query(o->ch[],k);
  81. return query(o->ch[],k-o->ch[]->s-);
  82. }
  83. void print(Node* &o)
  84. {
  85. if(o==null) return;
  86. print(o->ch[]);
  87. printf("%d ",o->v);
  88. print(o->ch[]);
  89. }
  90. void merge(Node* &big,Node* &sm)
  91. {
  92. if(sm==null) return;
  93. merge(big,sm->ch[]);
  94. merge(big,sm->ch[]);
  95. insert(big,sm->v);
  96. del(sm);
  97. }
  98. Node* root[maxn];
  99. int n,m;
  100. int first[maxn],next[maxn*],to[maxn*];
  101. void AddEdge(int a,int b)
  102. {
  103. to[++m]=b;
  104. next[m]=first[a];
  105. first[a]=m;
  106. }
  107. int First[maxn],Next[maxn],K[maxn],ans[maxn],Id[maxn];
  108. void addquery(int x,int k,int id)
  109. {
  110. K[++m]=k;
  111. Id[m]=id;
  112. Next[m]=First[x];
  113. First[x]=m;
  114. }
  115. void dfs(int x,int fa)
  116. {
  117. for(int i=first[x];i;i=next[i])
  118. {
  119. if(to[i]!=fa)
  120. {
  121. dfs(to[i],x);
  122. if(root[x]->s<root[to[i]]->s) swap(root[x],root[to[i]]);
  123. merge(root[x],root[to[i]]);
  124. }
  125. }
  126. for(int i=First[x];i;i=Next[i]) ans[Id[i]]=query(root[x],K[i]);
  127. }
  128. int main()
  129. {
  130. int Q,a,b;
  131. scanf("%d%d",&n,&Q);
  132. for(int i=;i<n;i++)
  133. {
  134. scanf("%d%d",&a,&b);
  135. AddEdge(a,b);
  136. AddEdge(b,a);
  137. }
  138. for(int i=;i<=n;i++)
  139. {
  140. root[i]=node();
  141. root[i]->s=;
  142. root[i]->ch[]=root[i]->ch[]=null;
  143. scanf("%d",&root[i]->v);
  144. }
  145. m=;
  146. for(int i=;i<=Q;i++)
  147. {
  148. scanf("%d%d",&a,&b);
  149. addquery(a,b,i);
  150. }
  151. dfs(,);
  152. for(int i=;i<=Q;i++) printf("%d\n",ans[i]);
  153. return ;
  154. }

还有DFS序+主席树的version。

  1. #include<cstdio>
  2. #include<cctype>
  3. #include<cstring>
  4. #include<algorithm>
  5. using namespace std;
  6. inline int read()
  7. {
  8. char ch=getchar();int sig=,x=;
  9. while(!isdigit(ch)) {if(ch=='-') sig=-;ch=getchar();}
  10. while(isdigit(ch)) x=x*+ch-'',ch=getchar();
  11. return x*sig;
  12. }
  13. const int maxn=;
  14. const int maxnode=;
  15. int s[maxnode],ls[maxnode],rs[maxnode],ToT;
  16. void update(int& y,int x,int l,int r,int pos)
  17. {
  18. s[y=++ToT]=s[x]+;if(l==r) return;
  19. ls[y]=ls[x];rs[y]=rs[x];int mid=l+r>>;
  20. if(pos<=mid) update(ls[y],ls[x],l,mid,pos);
  21. else update(rs[y],rs[x],mid+,r,pos);
  22. }
  23. int query(int x,int y,int l,int r,int k)
  24. {
  25. if(l==r) return l;
  26. int mid=l+r>>;
  27. if(s[ls[y]]-s[ls[x]]>=k) return query(ls[x],ls[y],l,mid,k);
  28. return query(rs[x],rs[y],mid+,r,k-s[ls[y]]+s[ls[x]]);
  29. }
  30. int to[maxn*],next[maxn*],first[maxn],e;
  31. void AddEdge(int a,int b)
  32. {
  33. to[++e]=b;next[e]=first[a];first[a]=e;
  34. to[++e]=a;next[e]=first[b];first[b]=e;
  35. }
  36. int L[maxn],R[maxn],v[maxn],root[maxn],pos[maxn],ts,siz[maxn];
  37. void dfs(int x,int fa)
  38. {
  39. L[x]=++ts;pos[ts]=x;siz[x]=;
  40. for(int i=first[x];i;i=next[i]) if(fa!=to[i]) dfs(to[i],x),siz[x]+=siz[to[i]];
  41. R[x]=ts;
  42. }
  43. int main()
  44. {
  45. int n=read(),q=read(),x,k;
  46. for(int i=;i<n;i++) AddEdge(read(),read());
  47. for(int i=;i<=n;i++) v[i]=read();
  48. dfs(,);
  49. for(int i=;i<=n;i++) update(root[i],root[i-],,n,v[pos[i]]);
  50. while(q--)
  51. {
  52. x=read();k=read();
  53. if(siz[x]>=k) printf("%d\n",query(root[L[x]-],root[R[x]],,n,k));
  54. else puts("-1");
  55. }
  56. return ;
  57. }

COJ1013 WZJ的数据结构(十三)的更多相关文章

  1. COJ967 WZJ的数据结构(负三十三)

    WZJ的数据结构(负三十三) 难度级别:C: 运行时间限制:7000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大 ...

  2. COJ 0967 WZJ的数据结构(负三十三)

    WZJ的数据结构(负三十三) 难度级别:E: 运行时间限制:7000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大 ...

  3. [COJ0985]WZJ的数据结构(负十五)

    [COJ0985]WZJ的数据结构(负十五) 试题描述 CHX有一个问题想问问大家.给你一个长度为N的数列A,请你找到两个位置L,R,使得A[L].A[L+1].…….A[R]中没有重复的数,输出R- ...

  4. [COJ0988]WZJ的数据结构(负十二)

    [COJ0988]WZJ的数据结构(负十二) 试题描述 输入 见题目,注意本题不能用文件输入输出 输出 见题目,注意本题不能用文件输入输出 输入示例 输出示例 数据规模及约定 1≤N≤1500,M≤N ...

  5. [COJ0989]WZJ的数据结构(负十一)

    [COJ0989]WZJ的数据结构(负十一) 试题描述 给出以下定义: 1.若子序列[L,R]的极差(最大值-最小值)<=M,则子序列[L,R]为一个均匀序列. 2.均匀序列[L,R]的权值为S ...

  6. COJ966 WZJ的数据结构(负三十四)

    WZJ的数据结构(负三十四) 难度级别:C: 运行时间限制:20000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给一棵n个节点的树,请对于形如"u  ...

  7. COJ970 WZJ的数据结构(负三十)

    WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计 ...

  8. COJ968 WZJ的数据结构(负三十二)

    WZJ的数据结构(负三十二) 难度级别:D: 运行时间限制:5000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有 ...

  9. COJ969 WZJ的数据结构(负三十一)

    WZJ的数据结构(负三十一) 难度级别:D: 运行时间限制:3000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 A国有两个主基站,供给全国的资源.定义一个主基站 ...

随机推荐

  1. yearProgress.vue

    <template> <div class="progressbar"> <el-progress :text-inside="true&q ...

  2. bzoj千题计划199:bzoj1055: [HAOI2008]玩具取名

    http://www.lydsy.com/JudgeOnline/problem.php?id=1055 区间DP dp[i][j][k] 表示区间[i,j]能否合成k #include<cst ...

  3. [整理]C 内核源代码-学习资料

    GNU C gnu项目:http://www.gnu.org/software/software.html ftp:http://ftp.gnu.org/gnu/ 托管:http://savannah ...

  4. [R语言]读取文件夹下所有子文件夹中的excel文件,并根据分类合并。

    解决的问题:需要读取某个大文件夹下所有子文件夹中的excel文件,并汇总,汇总文件中需要包含的2部分的信息:1.该条数据来源于哪个子文件夹:2.该条数据来源于哪个excel文件.最终,按照子文件夹单独 ...

  5. SQLSTATE[42000]

    SQLSTATE[42000]: Syntax error or access violation: 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT() ...

  6. G - DNA sequence HDU - 1560

    题目链接: https://vjudge.net/contest/254151#problem/G AC代码: #include<iostream> #include<cstring ...

  7. ViewGroup.layout(int l, int t, int r, int b)四个输入参数的含义

    ViewGroup.layout(int l, int t, int r, int b)这个方法是确定View的大小和位置的,然后将其绘制出来,里面的四个参数分别是View的四个点的坐标,他的坐标不是 ...

  8. Linux中断(interrupt)子系统之五:软件中断(softIRQ)

    转自:http://blog.csdn.net/droidphone/article/details/7518428 软件中断(softIRQ)是内核提供的一种延迟执行机制,它完全由软件触发,虽然说是 ...

  9. 过滤掉文本中的javascript标签代码

    2014年1月21日 11:51:19 php代码: $content = preg_replace('#<\s*[script].*>#', '', $a);//有些攻击可以在scrip ...

  10. 转:Vue-cli proxyTable 解决开发环境的跨域问题

    转:http://www.jianshu.com/p/95b2caf7e0da 和后端联调时总是会面对恼人的跨域问题,最近基于Vue开发项目时也遇到了这个问题,两边各自想了一堆办法,查了一堆资料,加了 ...