HDU 3966 樹鏈剖分學習

2021-07-05 01:50:34 字數 1671 閱讀 7248

這道題不難,看出是樹鏈剖分就很簡單,其實奇異也很明顯就是乙個樹鏈剖分,不過這次不是把樹鏈扔到線段樹上,是把節點扔到線段樹上。這個時候注意一下w[1] = 1就行了,其他就是線段樹的乙個區間覆蓋的問題了。

#include #include #include #include #include #include #define ll long long

#define for(i,x,y) for(int i = x;i < y;i ++)

#define ifor(i,x,y) for(int i = x;i > y;i --)

#define lrt rt<<1

#define rrt rt<<1|1

#define lson rt<<1,l,mid

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

#define maxn 55000

using namespace std;

int n,m,p;

struct edgeedge[maxn<<1];

int edge_cnt,head[maxn];

void add_edge(int u,int v)

int fa[maxn],top[maxn],sz[maxn],son[maxn],dep[maxn],w[maxn],val[maxn],totw;

void dfs1(int u,int father,int depth)

}son[u] = idd;

}void dfs2(int u,int father)

}struct treetree[maxn<<2];

void pushdown(int rt)

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

void modify(int rt,int l,int r,int value)

pushdown(rt);

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

if(r <= mid) modify(lrt,l,r,value);

else if(l > mid) modify(rrt,l,r,value);

else

}int query(int rt,int x)

pushdown(rt);

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

if(x <= mid) return query(lrt,x);

else return query(rrt,x);

}void c_modify(int l,int r,int value)

else

}if(l == r)

else if(dep[l] >= dep[r])

else modify(1,w[l],w[r],value);

}int main()

dfs1(1,-1,1);

totw = 0;

top[1] = 1;

w[1] = ++totw;

dfs2(1,-1);

build(1,1,totw);

for(i,0,p)

else if(op[0] == 'd')

else}}

return 0;

}

HDU3966 樹鏈剖分

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

hdu3966 樹鏈剖分

近期在強化知識點深度。發現樹鏈剖分不是非常會寫了。回想一下改動操作 若兩個點在同一條鏈上,則直接改動這段區間。若不在同一條鏈上,改動深度較大的點到其鏈頂端的區間,同一時候將這個點變為他所在鏈頂端的父親,迴圈操作直到這兩個點在同一條鏈上。就能夠用上一種方法了。沒實用lca寫是由於曾經被坑過,不但沒有這...

HDU3966 樹鏈剖分

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