• [CF932D]Tree


    题目大意:两种操作:

    1. $1;u;w:$把下一个点挂在$u$下,权值为$w$。
    2. $2;u;w:$询问从$u$开始的序列的最长长度。序列为从$u$开始的祖先序列中的不严格上升序列

    题解:可以把一个点的父亲设为它祖先中第一个比它大的,倍增即可

    卡点:跳父亲语句写在更新答案之前,然后锅锅

    C++ Code:

    #include <cstdio>
    #define maxn 400010
    #define N 20
    int cnt = 1, n, fa[N][maxn];
    long long sum[N][maxn], w[maxn], pw[maxn];
    long long last;
    int main() {
    	scanf("%d", &n);
    	pw[0] = 1; for (int i = 1; i < N; i++) pw[i] = pw[i - 1] << 1;
    	for (int i = 1; i <= n; i++) {
    		int op; long long u, W;
    		scanf("%d%lld%lld", &op, &u, &W);
    		u ^= last, W ^= last;
    		if (op == 1) {
    			w[++cnt] = W;
    			int now = u;
    			if (W > w[u]) {
    				for (int j = N - 1; ~j; j--) if (fa[j][now] && W > w[fa[j][now]]) now = fa[j][now];
    				now = fa[0][now];
    			}
    			fa[0][cnt] = now;
    			sum[0][cnt] = w[now];
    			for (int j = 1; j < N; j++) {
    				sum[j][cnt] = sum[j - 1][cnt] + sum[j - 1][fa[j - 1][cnt]];
    				fa[j][cnt] = fa[j - 1][fa[j - 1][cnt]];
    			}
    		} else {
    			last = 0;
    			if (w[u] > W) {
    				puts("0");
    				continue;
    			}
    			long long S = w[u];
    			for (int j = N - 1; ~j; j--) if (fa[j][u] && S + sum[j][u] <= W) {
    				S += sum[j][u];
    				u = fa[j][u];
    				last += pw[j];
    			}
    			printf("%lld
    ", last += 1);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    asp.net core grpc jwt身份验证
    (79)通过 .NET生成自签名证书
    chrome 命令
    asp.net core 配置证书身份验证
    OpenSSL 安装配置
    asp.net core proto
    asp.net core oss
    asp.net core skywalking
    asp.net core apollo
    图像旋转
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9797439.html
Copyright © 2020-2023  润新知