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

    改天补坑矩阵的差分

    树上差分:

    模型:树上多次区间修改.

    差分适用于修改多而询问少的情况

    类型:1.边差分 2.点差分

    边差分:把边的路径全部+x,把两个点的(u)(v的lca)算出来,然后在差分数组(dlt[u]+=x,dlt[v]+=x),在(dlt[lca(u,v)]-=2x)

    点差分:多次把点的点权加x,最后问点权最大为多少,这就是P3128 USACO15DEC

    做法在(dlt[lca(u,v)]-=x)并把(dit[fa(lca(u,v))]-=x). 因为(lca(u,v))也在u...v这条路径上,它同样需要被加x.回溯的时候会从u和v两个方向都给lca(u,v)加一个x,而它只能加一个,因此(dlt[lca(u,v)]-=x)。而(lca(u,v))的爸爸则根本无法被加,在(lca(u,v))已经只加一个x了,因此(dlt[fa[lca(u,v)]]-=x)就能让(lca(u,v))的爸爸不加x

    #include<cstdio>
    #include<iostream> 
    #define re register
    #define ll long long 
    #define maxn 50005
    using namespace std;
    struct edge{
    	int to,next;
    }e[maxn<<2];
    inline int read(){
    	int s=0;
    	char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') s=s*10+c-'0',c=getchar();
    	return s;
    }
    int head[maxn],power[maxn],n,m,d[maxn],fa[maxn][22],ans,tot;
    inline void add(int u,int v){e[++tot].to = v;e[tot].next = head[u];head[u] = tot;}
    inline void dfs(int u,int fath){
    	d[u]=d[fath]+1,fa[u][0]=fath;
    	for (re int i=0;fa[u][i];++i) fa[u][i+1]=fa[fa[u][i]][i];
    	for (re int i=head[u];i;i=e[i].next){
    		int v=e[i].to;
    		if (v!=fath) dfs(v,u);
    	}
    	return ;
    }
    inline int lca(int u,int v){
    	if(d[u] > d[v]) std::swap(u,v);
    	for(re int i = 20;i >= 0;i--) if(d[u] <= d[v] - (1<<i)) v = fa[v][i];
    	if(u == v) return u;
    	for(re int i = 20;i >= 0;i--) if(fa[u][i] != fa[v][i]) u = fa[u][i],v = fa[v][i];
    	return fa[u][0];
    }
    inline void get(int u,int f){
    	for(re int i = head[u];i;i = e[i].next){
    		int v = e[i].to;
    		if(v == f) continue;
    		get(v,u);
    		power[u] += power[v];
    	}
    	ans = std::max(ans,power[u]);
    }
    int main(){
    	n = read();m = read();
    	int x,y;
    	for(re int i = 1;i <= n - 1;i++){
    		x = read(), y = read();
    		add(x,y); add(y,x);
    	}
    	dfs(1,0);
    	for(re int i = 1;i <= m;i++){
    		x = read(), y = read();
    		int LCA = lca(x,y);
    		++power[x];++power[y];--power[LCA];--power[fa[LCA][0]];
    	}
    	get(1,0);
    	printf("%d
    ",ans);
    	return 0;
    }
    

    改日补个边差分 咕咕咕

  • 相关阅读:
    下载文件
    文件上传后台
    触发器
    存储过程
    火狐浏览器不能获取 event,解决js报错问题
    Oracle 数据库--一个用户同步的sql
    基于二进制的权限控制
    自定义jsp标签
    http,socket和websocket
    正向代理和反向代理
  • 原文地址:https://www.cnblogs.com/shikeyu/p/13393530.html
Copyright © 2011-2022 走看看