hdu 5274 樹鏈剖分

2021-07-10 22:55:44 字數 2545 閱讀 7832

解題思路:這道題據說是樹鏈剖分,所以也學習了一下。

不同的是這裡是點權值,我按照相似的處理方式,不知道為什麼wa了。。。調了好久。。

#include#include#includeusing namespace std;

const int maxn = 100005;

struct segment

tree[maxn<<2];

struct edge

edge[maxn<<1];

int a[maxn],son[maxn],top[maxn],w[maxn];

int dep[maxn],fa[maxn],size[maxn];

int cnt,num,pre[maxn];

int n,q,idx[maxn];

void addedge(int u,int v)

void dfs(int u) }}

void build_tree(int u,int tp)

}void build_segment(int rt,int l,int r)

void update(int rt,int pos,int val)

int mid = (tree[rt].l + tree[rt].r) >> 1;

if(pos <= mid) update(rt<<1,pos,val);

else update(rt<<1|1,pos,val);

tree[rt].sum = tree[rt<<1].sum ^ tree[rt<<1|1].sum;

}int query(int rt,int l,int r)

int find(int l,int r)

ans ^= query(1,w[f1],w[l]);

l = fa[f1], f1 = top[l];

} if(l == r) return ans^a[f1];

if(dep[l] > dep[r]) swap(l,r);

return ans ^= query(1,w[son[l]],w[r])^a[f1];

}int main()

dep[1] = 0;

dfs(1);

build_tree(1,1);

build_segment(1,1,num);

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

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

else

}} return 0;

}

ps:今天早上把這道題給a了,參考了一下別人的**,發現自己的**不一樣的地方就是在find函式裡,我是按照邊更新的方式去寫的,而這道題是點更新。關鍵是最後f1=f2後,如何把根節點加入進去。但仔細想想還是沒明白我的為什麼錯了。

#include#include#includeusing namespace std;

const int maxn = 100005;

struct segment

tree[maxn<<2];

struct edge

edge[maxn<<1];

int a[maxn],son[maxn],top[maxn],w[maxn];

int dep[maxn],fa[maxn],size[maxn];

int cnt,num,pre[maxn];

int n,q;

void addedge(int u,int v)

void dfs(int u) }}

void build_tree(int u,int tp)

}void build_segment(int rt,int l,int r)

void update(int rt,int pos,int val)

int mid = (tree[rt].l + tree[rt].r) >> 1;

if(pos <= mid) update(rt<<1,pos,val);

else update(rt<<1|1,pos,val);

tree[rt].sum = tree[rt<<1].sum ^ tree[rt<<1|1].sum;

}int query(int rt,int l,int r)

int find(int l,int r)

ans ^= query(1,w[f1],w[l]);

l = fa[f1], f1 = top[l];

} if(dep[l] > dep[r]) swap(l,r);//沒有比較l與r,這是關鍵點

return ans ^= query(1,w[l],w[r]);

}int main()

dep[1] = 0;

dfs(1);

build_tree(1,1);

build_segment(1,1,num);

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

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

}} 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的時候可以將兩種都不是當前正在處理的...