「SPOJ1487」Query on a tree III

传送门

把树的 \(\text{dfs}\) 序抠出来,子树的节点的编号位于一段连续区间,然后直接上建主席树区间第 \(k\) 大即可。

参考代码:

#include <algorithm>
#include <cstdio>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
template < class T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while ('0' > c || c > '9') f |= c == '-', c = getchar();
while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
s = f ? -s : s;
} const int _ = 1e5 + 5; int tot, head[_], nxt[_ << 1], ver[_ << 1];
inline void Add_edge(int u, int v)
{ nxt[++tot] = head[u], head[u] = tot, ver[tot] = v; } int n, q, a[_], X[_], dfn[_], rev[_], siz[_], pos[_];
int tt, rt[_], lc[_ << 5], rc[_ << 5], cnt[_ << 5]; inline void build(int& p, int l = 1, int r = n) {
p = ++tt;
if (l == r) return ;
int mid = (l + r) >> 1;
build(lc[p], l, mid), build(rc[p], mid + 1, r);
} inline void update(int& p, int q, int v, int l = 1, int r = n) {
p = ++tt, lc[p] = lc[q], rc[p] = rc[q], cnt[p] = cnt[q] + 1;
if (l == r) return ;
int mid = (l + r) >> 1;
if (v <= mid) update(lc[p], lc[q], v, l, mid);
else update(rc[p], rc[q], v, mid + 1, r);
} inline int query(int p, int q, int k, int l = 1, int r = n) {
if (l == r) return l;
int mid = (l + r) >> 1, num = cnt[lc[p]] - cnt[lc[q]];
if (num >= k) return query(lc[p], lc[q], k, l, mid);
else return query(rc[p], rc[q], k - num, mid + 1, r);
} inline void dfs(int u, int f) {
rev[dfn[u] = ++dfn[0]] = u, siz[u] = 1;
for (rg int i = head[u]; i; i = nxt[i]) {
int v = ver[i]; if (v == f) continue ;
dfs(v, u), siz[u] += siz[v];
}
} int main() {
read(n);
for (rg int i = 1; i <= n; ++i) read(a[i]), X[i] = a[i];
sort(X + 1, X + n + 1);
for (rg int i = 1; i <= n; ++i)
a[i] = lower_bound(X + 1, X + n + 1, a[i]) - X, pos[a[i]] = i;
for (rg int u, v, i = 1; i < n; ++i)
read(u), read(v), Add_edge(u, v), Add_edge(v, u);
dfs(1, 0), build(rt[0]);
for (rg int i = 1; i <= n; ++i) update(rt[i], rt[i - 1], a[rev[i]]);
read(q);
for (rg int l, r, x, k; q--; ) {
read(x), read(k), l = dfn[x], r = dfn[x] + siz[x] - 1;
printf("%d\n", pos[query(rt[r], rt[l - 1], k)]);
}
return 0;
}

最新文章

  1. hexo deploy出错的解决方法
  2. js阻止冒泡及jquery阻止事件冒泡示例介绍
  3. selenium如何高亮某元素和操作隐藏的内容
  4. Adobe Edge Animate –解决图形边缘精确检测问题-通过jquery加载svg图片
  5. cyg_flag 系列函数
  6. 缓存的概念(反向代理、CDN)
  7. codevs 1217 借教室
  8. 商品列表中显示类别名称而不是类别ID
  9. 关于继承UITableViewController若干问题
  10. [HTML5游戏开发]简单的《找没有同汉字版〗爆去考考您狄综力吧
  11. Ajax获取数据的几种格式和解析方式
  12. [HNOI2014]道路堵塞
  13. hdu4009最小树形图板子题
  14. 无法在Web服务器上启动调试。
  15. jquery attr方法获取input的checked属性问题
  16. ---转载---phython资料
  17. DataTable转换成实体
  18. Linux maven 下 jar包下载不下来的解决方法
  19. [转载]如何解决failed to push some refs to git
  20. shell 输出文件内容

热门文章

  1. JupyterLab远程访问配置方法(CentOS7)
  2. Python socket day2
  3. C语言:判断t所指字符串中的字母是否由连续递增字母组成。-判断一个输入的任何整数n,是否等于某个连续正整数序列之和。-将一副扑克牌编号为1到54,以某种方式洗牌,这种方式是将这副牌分成两半,然后将他们交叉,并始终保持编号1的牌在最上方。
  4. 使用在线编辑 svg 软件修改 svg 图片
  5. C# MD5加密-MD5Helper
  6. EasyUI中使用自定义的icon图标
  7. java编码格式大讲解
  8. sso系统登录以及jsonp原理
  9. ETCD的常用命令
  10. 吴裕雄 PYTHON 神经网络——TENSORFLOW 正则化