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;
}
然后……手贱打错变量名,调了一年…………
发现…………是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;
}
相关文章推荐
- [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)
- 【bzoj3531】[Sdoi2014]旅行 动态开点的线段树
- 【BZOJ3531】[Sdoi2014]旅行 树链剖分+动态开点线段树
- |BZOJ 3531|树链剖分|动态开点线段树|[Sdoi2014]旅行
- BZOJ[3531][Sdoi2014]旅行 树链剖分+动态开点线段树
- 【bzoj3531】 [SDOI2014]旅行 树链剖分+动态开点线段树
- BZOJ3531 [Sdoi2014]旅行——树剖+动态开点线段树
- 【块状树】【树链剖分】【线段树】bzoj3531 [Sdoi2014]旅行
- bzoj 3531 [Sdoi2014]旅行(树链剖分,线段树)
- [BZOJ3531][SDOI2014]旅行(树剖+线段树)
- [树链剖分 线段树] BZOJ 3531 [Sdoi2014]旅行
- [BZOJ3531][SDOI2014]旅行(链剖+线段树动态开点)
- BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)
- BZOJ 3531 [Sdoi2014]旅行 树链剖分 线段树
- 树链剖分+动态线段树(BZOJ-3531旅行)
- 【bzoj3531】[SDOI2014]旅行
- [BZOJ3531]SDOI2014旅行
- BZOJ 3531 SDOI2014 旅行(travel) 树链剖分模板题
- BZOJ-3531 旅行 树链剖分+动态开点线段树
- [bzoj3531][Sdoi2014]旅行