您的位置:首页 > 其它

BZOJ 3531: [Sdoi2014]旅行【树剖+动态开点线段树【听说有人写平衡树?【滑稽

2016-11-26 20:27 519 查看
刚开始看成了子树/链修改……想了一年23333

然后……手贱打错变量名,调了一年…………

发现…………是1A【233333

对于每个宗教开一棵树 就好了

删除直接赋值为0,反正不卡空间【滑稽

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define MAXV 4000005
#define MAXN 100005
using namespace std; int n,m;

int ROOT = 20000218;

inline int read(){
register char ch = getchar();
register int rtn = 0;
while(!isdigit(ch)) ch = getchar();
while(isdigit(ch)) rtn = rtn*10 + ch - '0' , ch = getchar();
return rtn;
}

struct t1{
int to,nxt;
}edge[MAXN<<1]; int cnt_edge;
int fst[MAXN];
void addedge(int x,int y){
edge[++cnt_edge].to = y;
edge[cnt_edge].nxt = fst[x];
fst[x] = cnt_edge;

edge[++cnt_edge].to = x;
edge[cnt_edge].nxt = fst[y];
fst[y] = cnt_edge;
}

int fth[MAXN] , top[MAXN] , siz[MAXN] , son[MAXN];
int dpt[MAXN];
int dfn[MAXN] , idf[MAXN] , cnt_dfs;
void dfs1(int now){
siz[now] = 1;
for(int tmp = fst[now];tmp;tmp=edge[tmp].nxt){
int aim = edge[tmp].to;
if(aim==fth[now]) continue;
fth[aim] = now;
dpt[aim] = dpt[now] + 1;
dfs1(aim);
siz[now] += siz[aim];
if(siz[aim]>siz[son[now]]) son[now] = aim;
}
}

void dfs2(int now,int tp){
top[now] = tp;
dfn[now] = ++cnt_dfs;
idf[cnt_dfs] = now;
if(son[now]) dfs2(son[now],tp);
for(int tmp = fst[now];tmp;tmp=edge[tmp].nxt){
int aim = edge[tmp].to;
if(aim==fth[now]|| aim==son[now]) continue;
dfs2(aim,aim);
}
}

int root[MAXN];
int w[MAXN] , c[MAXN];

struct NODE{
int left,right;
int sum,max;
}node[MAXV];
int cnt_node = 0;

void insert(int &now,int l,int r,int pos,int v){
if(!now) now = ++cnt_node;
if(l==r) return void((node[now].sum = node[now].max = v));
int mid = (l+r)>>1;
if(pos<=mid) insert(node[now].left,l,mid,pos,v);
else insert(node[now].right,mid+1,r,pos,v);
node[now].sum = node[node[now].left].sum + node[node[now].right].sum;
node[now].max = max(node[node[now].left].max , node[node[now].right].max);
}

void erase(int now,int l,int r,int pos){
if(l==r) return void((node[now].sum = node[now].max = 0));
int mid = (l+r)>>1;
if(pos<=mid) erase(node[now].left,l,mid,pos);
else erase(node[now].right,mid+1,r,pos);
node[now].sum = node[node[now].left].sum + node[node[now].right].sum;
node[now].max = max(node[node[now].left].max , node[node[now].right].max);
}

int inqry(int now,int l,int r,int L,int R,int opt){
if(!now) return 0;
if(L<=l&&r<=R) return opt?node[now].sum:node[now].max;
int mid = (l+r)>>1;
int rtn = 0;
if(L<=mid) rtn = inqry(node[now].left,l,mid,L,R,opt);
if(mid<R){
if(opt) rtn += inqry(node[now].right,mid+1,r,L,R,opt);
else rtn = max(rtn,inqry(node[now].right,mid+1,r,L,R,opt));
}
return rtn;
}

inline void work_ask(int u,int v,int opt){
int ans = 0;
int kk = root[c[v]];
while(top[u]^top[v]){
if(dpt[top[u]]<dpt[top[v]]) swap(u,v);
if(opt) ans += inqry(kk,1,n,dfn[top[u]],dfn[u],opt);
else ans = max(ans,inqry(kk,1,n,dfn[top[u]],dfn[u],opt));
u = fth[top[u]];
}
if(dpt[u]<dpt[v]) swap(u,v);
if(opt) ans += inqry(kk,1,n,dfn[v],dfn[u],opt);
else ans = max(ans,inqry(kk,1,n,dfn[v],dfn[u],opt));
printf("%d\n",ans);
}

char read_opt[10] ;
int read_x,read_y;
int main(){
// freopen("1.in","r",stdin);

n = read(),m = read();
ROOT%=n; ++ROOT;
for(int i=1;i<=n;++i) w[i] = read() , c[i] = read();
for(int i=1;i<n;++i) addedge(read(),read());

dpt[ROOT] = 1;
dfs1(ROOT);
dfs2(ROOT,ROOT);

for(int i=1;i<=n;++i) insert(root[c[i]],1,n,dfn[i],w[i]);

while(m--){
scanf("%s%d%d",read_opt,&read_x,&read_y);
if(read_opt[0]=='C'){
if(read_opt[1]=='C'){
erase(root[c[read_x]] ,1,n, dfn[read_x]);
c[read_x] = read_y;
insert(root[c[read_x]] ,1,n, dfn[read_x],w[read_x]);
}
else
insert(root[c[read_x]],1,n,dfn[read_x],w[read_x] = read_y);
}
else work_ask(read_x,read_y,read_opt[1]=='S');
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: