码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 6394 Tree 分块

时间:2018-08-14 11:41:13      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:lap   target   int   ==   for   namespace   fir   col   find   

Tree

题意: 给你一颗树, 每一个节点都有一个权值, 如果一个石头落在某个节点上, 他就会往上跳这个的点的权值步。 现在有2种操作, 1 把一个石头放在 x 的位置 询问有跳几次才跳出这棵树, 2 修改某个节点的权值。

解法:树上分块, 用dfs分好块之后。 对于每一块都处理出如果石头落在某个位置之后他跳出这个块之后的位置和次数。

每次更新都自己这一块的所有子节点, 然后找第k个父亲的时候用倍增优化。 

对于每次询问都跳到0号点之后,返回所经过的次数。

我们可以对属于同一块内的节点重新建立边, 因为我们在更新的时候不会直接访问到别的块的点, 所以重新建立边,避免遍历不需要的边(快了200ms)。

代码:

技术分享图片
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
  4 #define LL long long
  5 #define ULL unsigned LL
  6 #define fi first
  7 #define se second
  8 #define pb push_back
  9 #define lson l,m,rt<<1
 10 #define rson m+1,r,rt<<1|1
 11 #define max3(a,b,c) max(a,max(b,c))
 12 #define min3(a,b,c) min(a,min(b,c))
 13 typedef pair<int,int> pll;
 14 const int inf = 0x3f3f3f3f;
 15 const LL INF = 0x3f3f3f3f3f3f3f3f;
 16 const LL mod =  (int)1e9+7;
 17 const int N = 1e5 + 100;
 18 int n, m, b;
 19 int head[N], to[N], nt[N]; /// E1
 20 int head2[N], to2[N], nt2[N]; /// E2
 21 int Stack[N], belong[N];
 22 int jump[N], tto[N], cnt[N];
 23 int tot, top, type, tot2;
 24 int anc[N][20];
 25 inline void add2(int u, int v){
 26     to2[tot2] = v;
 27     nt2[tot2] = head2[u];
 28     head2[u] = tot2++;
 29 }
 30 inline void add(int u, int v){
 31     to[tot] = v;
 32     nt[tot] = head[u];
 33     head[u] = tot++;
 34 }
 35 void dfs(int u){
 36     int now = top, v;
 37     for(int i = head[u]; ~i; i = nt[i]){
 38         v = to[i];
 39         anc[v][0] = u;
 40         for(int i = 1; i < 20; i++)
 41             anc[v][i] = anc[anc[v][i-1]][i-1];
 42         dfs(v);
 43         if(top-now >= b){
 44             ++type;
 45             while(top!=now){
 46                 belong[Stack[top--]] = type;
 47             }
 48         }
 49     }
 50     Stack[++top] = u;
 51 }
 52 inline int Find(int x, int k){
 53     for(int i = 19; i >= 0; i--)
 54         if((k>>i)&1) x = anc[x][i];
 55     return x;
 56 }
 57 inline void Update(int x){
 58     int z = jump[x];
 59     if(belong[z] == belong[x]){
 60         tto[x] = tto[z];
 61         cnt[x] = cnt[z] + 1;
 62     }
 63     else {
 64         tto[x] = z;
 65         cnt[x] = 1;
 66     }
 67 }
 68 void Build(int x){
 69     Update(x);
 70     for(int i = head[x]; ~i; i = nt[i])
 71         Build(to[i]);
 72 }
 73 inline int solve(int p){
 74     int ret = 0;
 75     while(p){
 76         ret += cnt[p];
 77         p = tto[p];
 78     }
 79     return ret;
 80 }
 81 void dUpdate(int x){
 82     Update(x);
 83     for(int i = head2[x]; ~i; i = nt2[i]){
 84         dUpdate(to2[i]);
 85     }
 86 }
 87 void dfs2(int x){
 88     for(int i = head[x]; ~i; i = nt[i]){
 89         if(belong[x] == belong[to[i]]){
 90             add2(x, to[i]);
 91         }
 92         dfs2(to[i]);
 93     }
 94 }
 95 int main(){
 96     int t, x;
 97     scanf("%d", &t);
 98     while(t--){
 99         scanf("%d", &n);
100         b = sqrt(n);
101         tot = 0;top = 0; type = 0;tot2 = 0;
102         memset(head, -1, sizeof(int)*(n+1));
103         memset(head2, -1, sizeof(int)*(n+1));
104         for(int i = 2; i <= n; i++){
105             scanf("%d", &x);
106             add(x, i);
107         }
108         dfs(1);
109         while(top) belong[Stack[top--]] = type;
110         dfs2(1);
111         for(int i = 1; i <= n; i++){
112             scanf("%d", &x);
113             jump[i] = Find(i, x);
114         }
115         Build(1);
116         scanf("%d", &m);
117         int op, k;
118         while(m--){
119             scanf("%d", &op);
120             if(op == 1) {
121                 scanf("%d", &x);
122                 printf("%d\n", solve(x));
123             }
124             else {
125                 scanf("%d%d", &x, &k);
126                 jump[x] = Find(x, k);
127                 dUpdate(x);
128             }
129         }
130     }
131     return 0;
132 }
View Code

 

HDU 6394 Tree 分块

标签:lap   target   int   ==   for   namespace   fir   col   find   

原文地址:https://www.cnblogs.com/MingSD/p/9472349.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!