BZOJ3531 旅行 樹鏈剖分

2021-07-25 15:32:55 字數 1942 閱讀 2695

題目大意:給定一棵樹,點染色,修改點權,鏈上詢問點權和或者最大值

資料規模10^5

主要思想是對每種顏色開一顆線段樹,動態分配記憶體,染色時刪除原來的點,加入到新線段樹中即可。

需要注意的是不僅插入要更新資訊,刪除也要更新資訊。

自己的**:

#include

#include

#define safe(x,a) (x?x->a:0)

#define gm 100001

using

namespace

std;

const

int size=1

<<16;

int p,v,ll,rr;

int n,q;

inline

int __max(const

int &a,const

int &b)

int mid=x+y>>1;

if(p<=mid)

else

max=__max(safe(l,max),safe(r,max));

sum=safe(l,sum)+safe(r,sum);

}static

void

free(node*& kore,int x,int y)

int mid=x+y>>1;

if(p<=mid) free(kore->l,x,mid);

else

free(kore->r,mid+1,y);

if(!kore->l&&!kore->r)

kore->max=__max(safe(kore->l,max),safe(kore->r,max));

kore->sum=safe(kore->l,sum)+safe(kore->r,sum);

}void getsum(int x,int y)

int mid=x+y>>1;

if(ll<=mid&&l) l->getsum(x,mid);

if(midgetsum(mid+1,y);

}void getmax(int x,int y)

int mid=x+y>>1;

if(ll<=mid&&l) l->getmax(x,mid);

if(midgetmax(mid+1,y);

}}*s,*t,*f[size];

struct ar

void change(int pos,int val)

void

free(int pos)

int getsum(int l,int r)

int getmax(int l,int r)

}a[gm];

int tp=-1;

inline

void* node::operator

new(size_t)

return s++;

}inline

void node::operator

delete(void* p)

}int w[gm],c[gm];

struct e

}*f[gm];

#define link(a,b) f[a]=new e(b,f[a])

int sz[gm],fat[gm],son[gm],dpt[gm];

void dfs1(int x)

son[x]=maxs;

}int pos[gm],top[gm],ct=0;

void dfs2(int x)

}char o[3];

int z;

#define swap(x,y) z=x,x=y,y=z

int getsum(int x,int y)

int getmax(int x,int y)

int main()

}return

0;}

BZOJ 3531 旅行 樹鏈剖分 動態開點

題目鏈結 無優化版本 170行 首先樹剖可以維護樹上的鏈sum max 可以對每個宗教建一棵線段樹,那這題就很好做了 不過10 5需要動態開點 不明白為什麼nlogn不需要 就可以 不是每個insert加log個節點?操作修改完更改原數列!盲人。include include include def...

bzoj3531 Sdoi2014 旅行 樹剖

對每種宗教都建立線段樹,建立過程類似主席樹,在需要修改時動態建立線段樹 初始時不建立 所以空間複雜度是o nlog n ps 為什麼第二份會t啊 include include include define m 6000005 define inf 1 30 using namespace std ...

BZOJ 3531(樹鏈剖分 線段樹)

problem 旅行 bzoj 3531 題目大意 給定一顆樹,樹上的每個點有兩個權值 x,y 要求維護4種操作 操作1 更改某個點的權值x。操作2 更改某個點的權值y。操作3 求a b路徑上所有x屬性與a,b相同的點y屬性的和。操作4 求a b路徑上所有x屬性與a,b相同的點y屬性的最大值。n,q...