[cf contest 893(edu round 33)] F - Subtree Minimum Query

time limit per test

6 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

You are given a rooted tree consisting of n vertices. Each vertex has a number written on it; number ai is written on vertex i.

Let's denote d(i, j) as the distance between vertices i and j in the tree (that is, the number of edges in the shortest path from i to j). Also let's denote the k-blocked subtree of vertex x as the set of vertices y such that both these conditions are met:

  • x is an ancestor of y (every vertex is an ancestor of itself);
  • d(x, y) ≤ k.

You are given m queries to the tree. i-th query is represented by two numbers xi and ki, and the answer to this query is the minimum value of aj among such vertices j such that j belongs to ki-blocked subtree of xi.

Write a program that would process these queries quickly!

Note that the queries are given in a modified way.

Input

The first line contains two integers n and r (1 ≤ r ≤ n ≤ 100000) — the number of vertices in the tree and the index of the root, respectively.

The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109) — the numbers written on the vertices.

Then n - 1 lines follow, each containing two integers x and y (1 ≤ x, y ≤ n) and representing an edge between vertices x and y. It is guaranteed that these edges form a tree.

Next line contains one integer m (1 ≤ m ≤ 106) — the number of queries to process.

Then m lines follow, i-th line containing two numbers pi and qi, which can be used to restore i-th query (1 ≤ pi, qi ≤ n).

i-th query can be restored as follows:

Let last be the answer for previous query (or 0 if i = 1). Then xi = ((pi + last) modn) + 1, and ki = (qi + last) modn.

Output

Print m integers. i-th of them has to be equal to the answer to i-th query.

Example
input
5 21 3 2 3 52 35 13 44 121 22 3
output
25

我们对于树上的每一个节点开一个线段树(其实是可持久化的)。

每棵线段树都是一个[1..maxdepth]的按照绝对深度来建的线段树。

那么,对于每一个节点x,可以把所以它的子节点的线段树合并到它上面去。

但是这需要可持久化。因为当前节点的信息也要用到。如果不可持久化,可能会导致当前节点的地址在其他线段树里面存在。

实际上,每个地址只存在与一棵线段树中。

然后,由于父子节点之间的线段树只有1条链不同,所以要新建logn个节点。

总共有n-1对父子关系,所以空间为O(nlogn)。

时间复杂度为O(mlogn)。注意强制在线。

code:

 #include <cstdio>
 #include <cstring>
 #include <algorithm>
 typedef long long LL;
 using namespace std;

 void OJ() {
     #ifndef ONLINE_JUDGE
         freopen("in.txt","r",stdin);
         freopen("out.txt","w",stdout);
     #endif
 }

 namespace fastIO {
     #define gec(c) getchar(c)
     #define puc(c) putchar(c)
     char ch;
     inline int read() {
         ,f=; ch=getchar();
         ') {
             if (ch=='-') f=-f;
             ch=gec();
         }
         ') {
             x=(x<<)+(x<<)+(ch^);
             ch=gec();
         }
         return x*f;
     }
     ];
     template <class T> inline void write(T x) {
         ) {
             puc('); return;
         }
         ) x=-x,puc('-');
         ; x; x/=) nnn[++ttt]=x%;
         );
     }
     inline void newline () {
         puc('\n');
     }
 } using namespace fastIO;

 ,inf=2e9;
 int n,q,tot,lim;
 ],son[N<<],dep[N];
 struct node {
     node* l,* r;
     int v;
     node () {
         l=r=;
         v=inf;
     }
 } *ro[N];
 #define M ((l)+(r)>>1)
 inline void refresh (node* c) {
     c->v=inf;
     if (c->l) c->v=min(c->v,c->l->v);
     if (c->r) c->v=min(c->v,c->r->v);
 }
 inline void setup (node* &c,int l,int r,int x,int v) {
     c=new node();
     if (l==r) {
         c->v=v;
         return;
     }
     if (x<=M) setup(c->l,l,M,x,v);
     ,r,x,v);
     refresh(c);
 }
 inline node* merge (node* x,node* y) {
     if (!x||!y) return x?x:y;
     node* ret=new node();
     ret->l=merge(x->l,y->l);
     ret->r=merge(x->r,y->r);
     ret->v=min(x->v,y->v);
     return ret;
 }
 inline int reply (node* u,int l,int r,int x,int y) {
     if (!u) return inf;
     if (x<=l&&r<=y) return u->v;
     if (y<=M) return reply(u->l,l,M,x,y); else
     ,r,x,y); else
     ,r,x,y));
 }
 void add (int x,int y) {
     nxt[++tot]=lnk[x],lnk[x]=tot,son[tot]=y;
 }
 void dfs (int x,int p) {
     setup(ro[x],,n,dep[x]=dep[p]+,a[x]);
     lim=max(lim,dep[x]);
     for (int j=lnk[x]; j; j=nxt[j]) {
         if (son[j]==p) continue;
         dfs(son[j],x);
         ro[x]=merge(ro[x],ro[son[j]]);
     }
 }
 int main() {
     OJ(); ;
     n=read(),rot=read();
     ; i<=n; ++i) {
         a[i]=read(),ro[i]=;
     }
     ; i<n; ++i) {
         x=read(),y=read();
         add(x,y),add(y,x);
     }
     dep[]=lim=,dfs(rot,);
     q=read();
     for ( ; q; --q) {
         x=read(),y=read();
         x=(x+ans)%n+,y=(y+ans)%n;
         ans=reply(ro[x],,n,dep[x],min(lim,dep[x]+y));
         write(ans),newline();
     }
     ;
 }

[cf contest 893(edu round 33)] F - Subtree Minimum Query的更多相关文章

  1. EC Round 33 F. Subtree Minimum Query 主席树/线段树合并

    这题非常好!!! 主席树版本 很简单的题目,给一个按照指定节点的树,树上有点权,你需要回答给定节点的子树中,和其距离不超过k的节点中,权值最小的. 肯定首先一想,按照dfs序列建树,然后按照深度为下标 ...

  2. Educational Codeforces Round 33 (Rated for Div. 2) F. Subtree Minimum Query(主席树合并)

    题意 给定一棵 \(n\) 个点的带点权树,以 \(1\) 为根, \(m\) 次询问,每次询问给出两个值 \(p, k\) ,求以下值: \(p\) 的子树中距离 \(p \le k\) 的所有点权 ...

  3. Codeforces 893F - Subtree Minimum Query

    893F - Subtree Minimum Query 题意 给出一棵树,每次询问 \(x\) \(k\),求以 \(x\) 为根结点的子树中的结点到结点 \(x\) 的距离小于等于 \(k\) 的 ...

  4. CF893F Subtree Minimum Query 解题报告

    CF893F Subtree Minimum Query 输入输出格式 输入格式: The first line contains two integers \(n\) and \(r\) ( \(1 ...

  5. [CF893F] Subtree Minimum Query

    Description: 给定一棵树,每次询问某点子树中到其不超过k的所有点的最小点权 强制在线 Hint: \(n,m\le 10^5\) Solution: 看到题目第一反应是以深度为下标,dfs ...

  6. CF893F Subtree Minimum Query 主席树

    如果是求和就很好做了... 不是求和也无伤大雅.... 一维太难限制条件了,考虑二维限制 一维$dfs$序,一维$dep$序 询问$(x, k)$对应着在$dfs$上查$[dfn[x], dfn[x] ...

  7. Subtree Minimum Query CodeForces - 893F (线段树合并+线段树动态开点)

    题目链接:https://cn.vjudge.net/problem/CodeForces-893F 题目大意:给你n个点,每一个点有权值,然后这n个点会构成一棵树,边权为1.然后有q次询问,每一次询 ...

  8. 2019.01.19 codeforces893F.Subtree Minimum Query(线段树合并)

    传送门 线段树合并菜题. 题意简述:给一棵带点权的有根树,多次询问某个点ppp子树内距离ppp不超过kkk的点的点权最小值,强制在线. 思路: 当然可以用dfsdfsdfs序+主席树水过去. 然而线段 ...

  9. CF893F:Subtree Minimum Query(线段树合并)

    Description 给你一颗有根树,点有权值,m次询问,每次问你某个点的子树中距离其不超过k的点的权值的最小值.(边权均为1,点权有可能重复,k值每次询问有可能不同,强制在线) Input 第一行 ...

随机推荐

  1. CentOS7 配置ISCSI targetcli 共享存储

  2. mysql索引类型(按存储结构划分)

    关于mysql索引类型,网上有很多相关的介绍,给人的感觉很乱.鄙人在翻阅相关书籍后,特意梳理了一下.哪里有不对的地方,欢迎指正! 1. B-Tree索引 它使用B-Tree数据结构来存储数据,实际上很 ...

  3. pandas的基本功能(一)

    第16天pandas的基本功能(一) 灵活的二进制操作 体现在2个方面 支持一维和二维之间的广播 支持缺失值数据处理 四则运算支持广播 +add - sub *mul /div divmod()分区和 ...

  4. python操作MongoDB、MySQL、Postgres、Sqlite、redis实例

    总结:除了MongoDB.redis,其他三个数据库用python来操作其实是差不多的.所有例子都很简单,实际生产环境中的数据库操作远比这复杂得多,命令也比我例子中的多得多,我这里高级一点的用法就是批 ...

  5. Django路由控制

    本文目录 一 Django中路由的作用 二 简单的路由配置 三 有名分组 四 路由分发 五 反向解析 六 名称空间 七 django2.0版的path 回到目录 一 Django中路由的作用 URL配 ...

  6. APIO 2014 回文串(Manacher+后缀自动机+倍增)

    题意 https://www.lydsy.com/JudgeOnline/problem.php?id=3676 思路 好像还是回文自动机裸体,但是 \(\text{Manacher}\) +后缀自动 ...

  7. bootstrap:modal & iframe

    form提交绑定到特定的iframe & form的结果在dialog上显示 form:target属性 <!-- when the form is submitted, the ser ...

  8. vue安装之后的报错处理---chromedriver@2.35.0 install: `node install.js`

    报错:chromedriver@2.35.0 install: `node install.js` 这个错误的解决方法就是在你创建的项目目录,比如你创建的项目叫myVue,然后你就要在myVue这个目 ...

  9. Gradle 依赖管理

    依赖管理(在 build.gradle 中): 1.定义依赖仓库(repositories): Gradle 要求至少定义一个依赖仓库,依赖仓库可以是文件系统,也可以是中心服务器.最常用的是 jcen ...

  10. C#操作Control异步工具类

    /// <summary> /// 异步工具类 /// </summary> public class TaskTools { /// <summary> /// ...