[动态点分治] BZOJ3730: 震波
2017-02-15 14:35
316 查看
题意
给定N个点的一棵边权都为1的树,每个点有点权 。M次操作,两种类型1.单点点权修改。
2.给出x和k,询问到x的距离不超过K的所有点权和。
操作加密,强制在线。
N,M<=100000
题解
动态点分治。同样把信息收集到根。对于每个点分树,把所有点放到一个树状数组中,数状数组的下标即是到根的距离。要注意相同子树中的东西计算重复了,为了抠去重复部分,还需要对每个点分树再开一个数状数组,维护其中的点到父点分树的根的距离。这样修改和询问都是暴力爬树高,修改时在途中进行树状数组的单点修改,询问的话每次统计一下经过当前根的路径对应的权值和即可。
#include<cstdio> #include<queue> #include<algorithm> using namespace std; const int maxn=100005, maxe=200005; int n,m,w[maxn],last_print; int fir[maxn],nxt[maxe],son[maxe],tot; bool vis[maxn]; int sz[maxn]; //------------------------------------------------------------------------ int rt,allmin,allsz,MaxD,d[maxn]; int dfs_info(int x,int fa){ sz[x]=1; for(int j=fir[x];j;j=nxt[j]) if(son[j]!=fa&&!vis[son[j]]){ d[son[j]]=d[x]+1; MaxD=max(MaxD,d[son[j]]); dfs_info(son[j],x); sz[x]+=sz[son[j]]; } } void dfs_G(int x,int fa){ int _max=0; for(int j=fir[x];j;j=nxt[j]) if(son[j]!=fa&&!vis[son[j]]){ dfs_G(son[j],x); _max=max(_max,sz[son[j]]); } if(allmin>max(_max,allsz-sz[x])) allmin=max(_max,allsz-sz[x]), rt=x; } int find_G(int x){ allmin=1e+9; MaxD=d[x]=0; dfs_info(x,0); allsz=sz[x]; dfs_G(x,0); return rt; } //------------------------------------------------------------------------ int dep[maxn],anc[maxn][25]; void dfs_LCA(int x,int fa){ anc[x][0]=fa; for(int j=1;j<=20;j++) anc[x][j]=anc[anc[x][j-1]][j-1]; for(int j=fir[x];j;j=nxt[j]) if(son[j]!=fa) dep[son[j]]=dep[x]+1, dfs_LCA(son[j],x); } int LCA(int x,int y){ if(dep[x]<dep[y]) swap(x,y); for(int j=20;j>=0;j--) if(dep[anc[x][j]]>=dep[y]) x=anc[x][j]; if(x==y) return x; for(int j=20;j>=0;j--) if(anc[x][j]!=anc[y][j]) x=anc[x][j], y=anc[y][j]; return anc[x][0]; } int getDis(int x,int y){ return dep[x]+dep[y]-dep[LCA(x,y)]*2; } //------------------------------------------------------------------------ vector< int > bit[maxn][2]; void bit_Updata(int k1,int k2,int x,int val){ int len=bit[k1][k2].size()-1; for(x++;x<=len;x+=(x&(-x))) bit[k1][k2][x]+=val; } int bit_Query(int k1,int k2,int x){ int res=0, len=bit[k1][k2].size()-1; for(x=min(x+1,len);x;x-=(x&(-x))) res+=bit[k1][k2][x]; return res; } //------------------------------------------------------------------------ int prt[maxn]; void dfs_push(int x,int fa,int id){ bit_Updata(id,0,getDis(x,id),w[x]); if(prt[id]) bit_Updata(id,1,getDis(x,prt[id]),w[x]); for(int j=fir[x];j;j=nxt[j]) if(son[j]!=fa&&!vis[son[j]]) dfs_push(son[j],x,id); } void DivTree(int x,int faG){ int G=find_G(x); prt[G]=faG; vis[G]=true; bit[G][0].resize(allsz+3); bit[G][1].resize(allsz+3); dfs_push(G,0,G); for(int j=fir[G];j;j=nxt[j]) if(!vis[son[j]]) DivTree(son[j],G); } void Updata(int x,int val){ for(int y=x;y;y=prt[y]){ bit_Updata(y,0,getDis(x,y),val-w[x]); if(prt[y]) bit_Updata(y,1,getDis(x,prt[y]),val-w[x]); } } int Query(int x,int K){ int res=bit_Query(x,0,K); for(int y=x;prt[y];y=prt[y]) if(K>=getDis(x,prt[y])) res+=bit_Query(prt[y],0,K-getDis(x,prt[y]))-bit_Query(y,1,K-getDis(x,prt[y])); return res; } //------------------------------------------------------------------------ void add(int x,int y){ son[++tot]=y; nxt[tot]=fir[x]; fir[x]=tot; } int getint(){ int res=0; char ch=getchar(); while(!('0'<=ch&&ch<='9')) ch=getchar(); while('0'<=ch&&ch<='9') res=res*10+ch-'0', ch=getchar(); return res; } int main(){ freopen("bzoj3730.in","r",stdin); freopen("bzoj3730.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) w[i]=getint(); for(int i=1;i<=n-1;i++){ int x=getint(),y=getint(); add(x,y); add(y,x); } dfs_LCA(1,0); DivTree(1,0); while(m--){ int pd=getint(),x=getint(),y=getint(); x^=last_print; y^=last_print; if(!pd) printf("%d\n",last_print=Query(x,y)); else Updata(x,y), w[x]=y; } return 0; }
相关文章推荐
- 【BZOJ3730】震波(动态点分治)
- 【BZOJ3730】震波(动态点分治)
- [BZOJ3730]震波(动态点分治)
- 【BZOJ-3730】震波 动态点分治 + 树状数组
- bzoj 3730: 震波 (动态点分治)
- [BZOJ3730]震波-动态点分治
- [bzoj3730][点分治]震波
- 动态点分治:bzoj 3730,bzoj 1095
- 【bzoj3730】震波【动态树分治】
- BZOJ 3730: 震波 动态树分治 线段树 lca
- 【bzoj3295】动态逆序对 CDQ分治
- BZOJ4012【动态点分治】
- [BZOJ3295] [Cqoi2011]动态逆序对 (树套树)or(CDQ分治)
- [BZOJ3730][震波][动态树分治+线段树+LCA]
- 【bzoj3924】[Zjoi2015]幻想乡战略游戏 动态点分治
- [BZOJ4012][HNOI2015]开店(动态点分治)
- BZOJ4012 [HNOI2015]开店 【动态点分治 + splay】
- BZOJ 3730 震波
- 【BZOJ1095】捉迷藏(动态点分治)
- Bzoj3730: 震波