題目大意:給定一棵樹,點染色,修改點權,鏈上詢問點權和或者最大值
資料規模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...