CF893F Subtree Minimum query 主席树

Posted itst

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF893F Subtree Minimum query 主席树相关的知识,希望对你有一定的参考价值。

传送门


 

要是不强制在线,这题线段树合并or长链剖分直接暴搞好伐

但是强制在线就有些麻烦了

我们这么考虑:建立主席树,第$i$棵树存深度$leq i$的点的信息,那么我们每一次$query$的时候,直接查询$dep_x+k$对应的主席树上$x$的子树对应区间的最小权值即可。

很板子的一道主席树题

  1 #include<bits/stdc++.h>
  2 #define INF 0x7fffffff
  3 #define mid ((l + r) >> 1)
  4 //This code is written by Itst
  5 using namespace std;
  6 
  7 inline int read(){
  8     int a = 0;
  9     bool f = 0;
 10     char c = getchar();
 11     while(c != EOF && !isdigit(c)){
 12         if(c == -)
 13             f = 1;
 14         c = getchar();
 15     }
 16     while(c != EOF && isdigit(c)){
 17         a = (a << 3) + (a << 1) + (c ^ 0);
 18         c = getchar();
 19     }
 20     return f ? -a : a;
 21 }
 22 
 23 const int MAXN = 100010;
 24 struct node{
 25     int l , r , minN;
 26 }Tree[MAXN * 30];
 27 struct Edge{
 28     int end , upEd;
 29 }Ed[MAXN << 1];
 30 vector < int > num[MAXN];
 31 int root[MAXN] , head[MAXN] , size[MAXN] , dfn[MAXN] , dep[MAXN] , val[MAXN];
 32 int rt , T , N , M , cntEd , cntNode , maxD , ts;
 33 
 34 inline void addEd(int a , int b){
 35     Ed[++cntEd].end = b;
 36     Ed[cntEd].upEd = head[a];
 37     head[a] = cntEd;
 38 }
 39 
 40 void dfs(int x , int p){
 41     dfn[x] = ++ts;
 42     dep[x] = dep[p] + 1;
 43     maxD = max(maxD , dep[x]);
 44     num[dep[x]].push_back(x);
 45     size[x] = 1;
 46     for(int i = head[x] ; i ; i = Ed[i].upEd)
 47         if(Ed[i].end != p){
 48             dfs(Ed[i].end , x);
 49             size[x] += size[Ed[i].end];
 50         }
 51 }
 52 
 53 int insert(int now , int l , int r , int tar , int num){
 54     int x = ++cntNode;
 55     Tree[x] = Tree[now];
 56     Tree[x].minN = min(Tree[x].minN , num);
 57     if(l != r)
 58         if(mid >= tar)
 59             Tree[x].l = insert(Tree[x].l , l , mid , tar , num);
 60         else
 61             Tree[x].r = insert(Tree[x].r , mid + 1 , r , tar , num);
 62     return x;
 63 }
 64 
 65 int query(int root , int l , int r , int L , int R){
 66     if(!root)
 67         return INF;
 68     if(l >= L && r <= R)
 69         return Tree[root].minN;
 70     int minN = INF;
 71     if(mid >= L)
 72         minN = query(Tree[root].l , l , mid , L , R);
 73     if(mid < R)
 74         minN = min(minN , query(Tree[root].r , mid + 1 , r , L , R));
 75     return minN;
 76 }
 77 
 78 int main(){
 79 #ifndef ONLINE_JUDGE
 80     freopen("893F.in" , "r" , stdin);
 81     //freopen("893F.out" , "w" , stdout);
 82 #endif
 83     N = read();
 84     rt = read();
 85     Tree[0].minN = INF;
 86     for(int i = 1 ; i <= N ; ++i)
 87         val[i] = read();
 88     for(int i = 1 ; i < N ; ++i){
 89         int a = read() , b = read();
 90         addEd(a , b);
 91         addEd(b , a);
 92     }
 93     dfs(rt , 0);
 94     for(int i = 1 ; i <= maxD ; ++i){
 95         root[i] = root[i - 1];
 96         for(int j = 0 ; j < num[i].size() ; ++j)
 97             root[i] = insert(root[i] , 1 , N , dfn[num[i][j]] , val[num[i][j]]);
 98     }
 99     int lastans = 0;
100     for(M = read() ; M ; --M){
101         int a = (read() + lastans) % N + 1 , b = (read() + lastans) % N;
102         printf("%d
" , lastans = query(root[min(maxD , dep[a] + b)] , 1 , N , dfn[a] , dfn[a] + size[a] - 1));
103     }
104     return 0;
105 }

以上是关于CF893F Subtree Minimum query 主席树的主要内容,如果未能解决你的问题,请参考以下文章

CF893F Subtree Minimum Query 主席树

Minimum Subtree

Minimum Subtree

lintcode596- Minimum Subtree- easy

题解CF1324F Maximum White Subtree

cf 627 F. Maximum White Subtree树形dp