zoukankan      html  css  js  c++  java
  • 树上差分

    [模板题]https://www.luogu.com.cn/problem/P3128

    在(u,v)最短路径上每个点加上v,询问最后权值最大的点

    const int N = 5e4 + 50,M = 1e5 +50;
    int h[N],e[M],ne[M],idx;
    void add(int a,int b) {
    	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    }
    
    int n,m,root;
    int dep[N],f[N][31];//i结点的2^j辈祖先
    int cf[N];//差分数组,记录结点的子树权值和
    
    void dfs(int u,int fa) {//预处理
    	dep[u]=dep[fa]+1;
    	for(int i=0; i<30; i++) {  //注意这里不取等号
    		f[u][i+1]=f[f[u][i]][i];
    	}
    	for(int i=h[u]; ~i; i=ne[i]) {
    		int j=e[i];
    		if(j == fa)continue;
    		f[j][0]=u;
    		dfs(j,u);
    	}
    }
    
    int lca(int x,int y) {
    	if(dep[x]<dep[y])swap(x,y);
    	for(int i=30; i>=0; i--) {   //x,y跳到同一深度
    		if(dep[f[x][i]]>=dep[y])x=f[x][i];
    		if(x == y)return x;
    	}
    	for(int i=30; i>=0; i--) {
    		if(f[x][i]!=f[y][i]) {
    			x=f[x][i];
    			y=f[y][i];
    		}
    	}
    	return f[x][0];//共同的fa
    }
    
    int maxn;
    void find_ans(int u,int fa) {
    	for(int i=h[u]; ~i; i=ne[i]) {
    		int j = e[i];
    		if(j == fa)continue;
    		find_ans(j,u);
    		cf[u] += cf[j];   //cf[u]存u结点所有子树的权值和
    	}
    	maxn = max(maxn,cf[u]);
    }
    
    void work() {
    	scanf("%d%d",&n,&m);
    	memset(h,-1,sizeof(h));
    	for(int i=1; i<n; i++) {
    		int u,v;scanf("%d%d",&u,&v);
    		add(u,v);add(v,u);
    	}
    	dfs(1,0);
    	while(m--) {
    		int u,v;
    		scanf("%d%d",&u,&v);
    		int ans = lca(u,v);
    		cf[u]++;   //点权差分
    		cf[v]++;
    		cf[ans]--;
    		cf[f[ans][0]]--;
    		/*边权差分
    		cf[u]+=1;
    		cf[v]+=1;
    		cf[ans]-=2;
    		*/
    	}
    	maxn = 0;
    	find_ans(1,-1);
    	printf("%d
    ",maxn);
    }
    
  • 相关阅读:
    基于雪花算法的单机版
    Spring cloud gateway自定义filter以及负载均衡
    logback转义符与MDC
    录音地址文件保存
    maven加载本地jar
    ES Log4J配置信息
    java线程池
    openstreetmap的数据下载
    php更新版本后(路径更改后)要做的调整
    重启IIS
  • 原文地址:https://www.cnblogs.com/LaiYiC/p/15236503.html
Copyright © 2011-2022 走看看