HDU 5293 樹鏈剖分

2021-07-10 06:07:15 字數 2158 閱讀 6495

(

題意:給定一棵樹,一些鏈,選出最多的鏈不相交。

解法:定義 sum[u] = sim(dp[v]) ( v = son[u] )

dp[u]為u這顆子樹,最多能選的鏈數。

當有一條鏈a,b,lca(a,b)=u

dp[u] = sum[u] - dp[a1] + sum[a1] - dp[a2] … + sum[a]

這樣就可以用樹鏈剖分搞啦~

#pragma comment(linker, "/stack:1024000000,1024000000")

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

//#include

//#include

#include

//#pragma comment(linker, "/stack:1024000000,1024000000")

using

namespace

std;

#define lson l, m, rt<<1

#define rson m+1, r, rt<<1|1

#define inf 1e9

#define debug(a) cout << #a" = " << (a) << endl;

#define debugarry(a, n) for (int i = 0; i < (n); i++)

#define clr(x, y) memset(x, y, sizeof x)

#define ll long long

#define ull unsigned long long

#define for(i,a,b) \

for(i=a;a=b;aconst

int maxn = 100000+30;

struct sadg[maxn<<2];

int h[maxn],si;

void add(int u,int v)

int siz[maxn],dep[maxn];

int fa[maxn],son[maxn],top[maxn];

void dfs1(int u,int f,int d)

}int rs[maxn];

void upp(int x,int p)

}int get(int x)

return ret;

}int query(int u,int v)

if( dep[u] > dep[v] ) swap(u,v);

return ret += get(p[v]) - get(p[u]-1);

}int lca(int u,int v)

void init()

int uu[maxn],vv[maxn],val[maxn];

int dp[maxn] , sum[maxn];

vector

q[maxn];

void dfs(int u,int f)

}upp(p[u],sum[u]);

dp[u] = sum[u];

for(int i=0;iint j=q[u][i];

dp[u] = max( dp[u] , query(uu[j],vv[j]) + val[j] );

}upp(p[u],-dp[u]);

}int main()

clr(dp,0);

clr(sum,0);

clr(rs,0);

for(int i=1;i<=n;i++)

q[i].clear();

dfs1(1,-1,1);

dfs2(1,1);

for(int i=0;iscanf("%d%d%d",&uu[i],&vv[i],&val[i]);

q[lca(uu[i],vv[i])].push_back(i);

}dfs(1,-1);

printf("%d\n",dp[1]);

}return

0;}

樹鏈剖分 樹鏈剖分講解

好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 vector v maxn int size maxn dep maxn val maxn id maxn hson maxn top maxn fa maxn 定義 int edge 1,num 1 struct tree e ma...

HDU3966 樹鏈剖分

題目 aragorn s story 題意 給一棵樹,並給定各個點權的值,然後有3種操作 i c1 c2 k 把c1與c2的路徑上的所有點權值加上k d c1 c2 k 把c1與c2的路徑上的所有點權值減去k q c 查詢節點編號為c的權值 分析 典型的樹鏈剖分題目,先進行剖分,然後用線段樹去維護即...

hdu5029 樹鏈剖分

這題絕對好題。題意很簡單,也很容易想到樹鏈剖分,之後就不太好做了。開始想的是按顏色排序,然後每次處理一種顏色,求出最優解。這樣做的話,最壞情況會退化到n 2,不可接受。之後用線段樹維護,乙個節點只存在一種顏色,而且排序之後能保證在樹中顏色不會交叉,pushdown的時候可以將兩種都不是當前正在處理的...