Differential study notes tree

Learning Link: https://www.sohu.com/a/271430685_100201031

There are two ways a tree difference:

A point of difference: changing the tree path (u, v) on all points weights point, assuming increased value val

We maintain a differential tag array as an array for each node

Consider the impact of change?

tag[u]+=val,tag[v]+=val,tag[lca(u,v)]-=val,tag[fa(lca(u,v))]-=val;

On the same path, we change the weights endpoints, such respectively from u, v back, we can find the right on all points of the value of this path!

Then consider the fa [lca (u, v)] of weight to lose val, because we operate on the chain (u, v) should not affect the chain outside the node!

Can generally be treated in a manner doubling seeking LCA

example:

1. Luo Gu: P3128 [USACO15DEC] maximum flow Max Flow

CODE:

/*

*/
#include<cstdio>
using namespace std;
const int N=500020,logN=19;
struct node{
int from;
int to;
int next;
}e[N<<1];
int head[N],num,n,m,log[N],f[N][logN],dep[N],tag[N],ans;
inline int max(int x,int y)
{
return x>y?x:y;
}
void addedge(int from,int to)
{
e[++num].next=head[from];
e[num].to=to;
e[num].from=from;
head[from]=num;
}
void swap(int &a,int &b)
{
int c=a;
a=b;
b=c;
}
void init()
{
log[0]=-1;
for(int i=1;i<=n;i++)
log[i]=log[i>>1]+1;
return;
}
void dfs(int u,int fa)
{
tag[u]=0;
dep[u]=dep[fa]+1;
f[u][0]=fa;
for(int i=1;i<=log[dep[u]];i++)
f[u][i]=f[f[u][i-1]][i-1];

for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(v!=fa)
dfs(v,u);
}
}
int ask(int x,int y)
{
if(dep[x]<dep[y])
swap(x,y);
while(dep[x]>dep[y])
x=f[x][log[dep[x]-dep[y]]];
if(x==y)
return x;
for(int i=log[dep[x]];i>=0;i--)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
void work(int u,int fa)
{
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(v!=fa)
{
work(v,u);
tag[u]+=tag[v];
}
}
ans=max(ans,tag[u]);
}
int main()
{
int x,y;
scanf("%d%d",&n,&m);
for(int i=1;i<=n-1;i++)
{
scanf("%d%d",&x,&y);
addedge(x,y);
addedge(y,x);
}
//LCA²¿·Ö
init();
dfs(1,0);
//Ê÷Éϲî·ÖµÄÏêϸ¹ý³Ì
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
tag[x]++;
tag[y]++;
int LCA=ask(x,y);
tag[LCA]--;
tag[f[LCA][0]]--;
}
work(1,0);//×îºó´Ó¸ù¿ªÊ¼Í³¼Æans,×¢ÒâÇ°ºóµÄ¸ù²»¿ÉÒÔ¸ü»»£¡
printf("%d",ans);
return 0;
}

Second edge difference:

Consider for a strand, the depth of the larger dots placed on his right side, which can ensure that each edge corresponds to a unique point!

Then, one side of the number of passes required for the path (u, v), referred tag [u] ++, tag [v] ++, tag [lca (u, v)] - = 2;

Because lca (u, v) is lca path of his father, not after he was counted twice, it can be deleted!

Example: transport plan

 

Guess you like

Origin www.cnblogs.com/little-cute-hjr/p/11787581.html