這道題不難,看出是樹鏈剖分就很簡單,其實奇異也很明顯就是乙個樹鏈剖分,不過這次不是把樹鏈扔到線段樹上,是把節點扔到線段樹上。這個時候注意一下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的權值 分析 典型的樹鏈剖分題目,先進行剖分,然後用線段樹去維護即...