hdu 3966 樹鏈剖分 模板題

2021-08-01 10:54:02 字數 1860 閱讀 2798

題意:給一棵樹,並給定各個點權的值,然後有3種操作:

i c1 c2 k: 把c1與c2的路徑上的所有點權值加上k

d c1 c2 k:把c1與c2的路徑上的所有點權值減去k

q c:查詢節點編號為c的權值

分析:典型的樹鏈剖分題目,先進行剖分,然後用線段樹去維護即可,注意hdu的oj採用windows系統,容易爆棧,所以在**

前面加上:#pragma comment(linker, 「/stack:1024000000,1024000000」)進行手動擴棧。

下面有**和注釋

純模板:

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

#include

#include

#include

#include

#include

using

namespace

std;

const

int n=50010;

int n,m,q;

int tim;

int num[n],siz[n],top[n],son[n];

int dep[n],tid[n],ran[n],fa[n];

int head[n],to[2*n],nex[2*n],edge;

void init()

void addedge(int u,int v)

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

}}void dfs2(int u,int tp)

}#define lson l,mid,rt<<1

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

int sum[4*n],col[4*n];

void pushup(int rt)

void pushdown(int rt,int m)

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

int mid=(l+r)>>1;

build(lson);

build(rson);

pushup(rt);

}void update(int l,int r,int v,int l,int r,int rt)

pushdown(rt,r-l+1);

int mid=(l+r)>>1;

if(l<=mid)

if(r>mid)

update(l,r,v,rson);

pushup(rt);

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

pushdown(rt,r-l+1);

int mid=(l+r)>>1;

int ret=0;

if(val<=mid) ret=query(lson,val);

else ret=query(rson,val);

pushup(rt);

return ret;

}void change(int x,int y,int val)

if(dep[x]>dep[y]) swap(x,y);

update(tid[x],tid[y],val,1,n,1);

}int main()

dfs1(1,0,0);

dfs2(1,1);

build(1,n,1);

while(q--)

else}}

}

**加注釋:

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

} }

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的權值 分析 典型的樹鏈剖分題目,先進行剖分,然後用線段樹去維護即...