bzoj P4034 HAOI2015 樹上操作

2021-08-04 15:10:51 字數 2432 閱讀 7539

傳送門

這題也有更高超的方法,用線段樹維護dfs序,對於dfs序中出現的節點我們乙個取正乙個取負,就可以直接上線段樹了。

樹剖**:

#include#include#define ll long long

using namespace std;

const int maxn=100005;

struct nodet[maxn*2];

struct segmentqt[maxn*4];

int w[maxn],head[maxn],fa[maxn],depth[maxn],size[maxn],top[maxn],pos[maxn],son[maxn];

int n,m,cnt,tmp;

inline void insert(int u,int v)

void dfs1(int x)

}void dfs2(int x,int tp)

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

inline void change(int x,int d,int rt)

if(x<=mid)change(x,d,rt<<1);

else change(x,d,rt<<1|1);

qt[rt].sum=qt[rt<<1].sum+qt[rt<<1|1].sum;

}inline void pushdown(int rt)

inline void add(int lf,int rf,int rt,ll d)

pushdown(rt);

if(lf<=mid)add(lf,rf,rt<<1,d);

if(rf>mid)add(lf,rf,rt<<1|1,d);

qt[rt].sum=qt[rt<<1].sum+qt[rt<<1|1].sum;

}inline ll query(int lf,int rf,int rt)

inline ll qmax(int x,int y)

int main()

dfs1(1);

dfs2(1,1);

build(1,n,1);

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

change(pos[i],w[i],1);

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

if(opt==2)

if(opt==3)

} return 0;

}

dfs序的**:

#include#include#define ll long long

using namespace std;

const int maxn=100005;

struct nodet[maxn*2];

struct segmentqt[maxn*2*4];

int w[maxn],head[maxn],_dfs[maxn*2],_c[maxn][3],_w[maxn*2],fa[maxn];

bool f[maxn];

int cnt,n,m,tmp;

inline void insert(int u,int v)

void dfs(int x)

_dfs[++tmp]=x;

_c[x][1]=tmp;

_w[tmp]=-w[x];

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

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

build(l,mid,rt<<1);

build(mid+1,r,rt<<1|1);

qt[rt].sum=qt[rt<<1].sum+qt[rt<<1|1].sum;

qt[rt].flag=qt[rt<<1].flag+qt[rt<<1|1].flag;

}inline void pushdown(int x,int l,int r)

inline void add(int l,int r,int lf,int rf,int rt,int d)

pushdown(rt,l,r);

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

if(lf<=mid)add(l,mid,lf,rf,rt<<1,d);

if(rf>mid)add(mid+1,r,lf,rf,rt<<1|1,d);

qt[rt].sum=qt[rt<<1].sum+qt[rt<<1|1].sum;

}inline ll query(int l,int r,int lf,int rf,int rt)

int main()

dfs(1);

build(1,n*2,1);

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

if(opt==2)

if(opt==3)

} return 0;

}

4034 HAOI2015 樹上操作

黈力 小貓 先用樹剖搞出dfs序,再用樹狀陣列差分維護 答案 對於第一種操作,子樹中的每乙個點都被加上a,直接區間加就好了。對於第二種操作,每個點增加的值為 deep y deep x 1 a,對此可以分成兩部分,一部分是 deep x 1 a,同第一種操作一樣處理,另一部分是deep y a,可再...

bzoj4034 HAOI2015 樹上操作

傳送門 description 有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個 操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。input 第一行包含...

bzoj 4034 HAOI2015 樹上操作

4034 haoi2015 樹上操作 time limit 10 sec memory limit 256 mb submit 4216 solved 1340 submit status discuss description 有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個 ...