BZOJ 3589 动态树
2017-04-25 22:39
316 查看
题意:给一棵树,点有点权,要求支持
1.子树点权+
2.询问k(k<=5)条链并集点权和
题目中所给链全部为某点到根路径上的一段
Sol:
子树点权加?DFS序
再来个询问链上点权和?树链剖分+DFS序
k条并集点权和?观察到k比较小,果断容斥
由数学必修一知识可知,若干集合交集=每个集合-每两个集合并+每三个集合并...
ans=Sum{一条}-Sum{两条交}+Sum{三链交}...
复杂度O(m*log^2(n)*2^k)
一如既往的乱七八糟,字面意义上的
题目要求答案mod(2^31),我们可以用int自然溢出最后答案&(2147483647) (就是2^31 -1 啦
Code:
1.子树点权+
2.询问k(k<=5)条链并集点权和
题目中所给链全部为某点到根路径上的一段
Sol:
子树点权加?DFS序
再来个询问链上点权和?树链剖分+DFS序
k条并集点权和?观察到k比较小,果断容斥
由数学必修一知识可知,若干集合交集=每个集合-每两个集合并+每三个集合并...
ans=Sum{一条}-Sum{两条交}+Sum{三链交}...
复杂度O(m*log^2(n)*2^k)
一如既往的乱七八糟,字面意义上的
题目要求答案mod(2^31),我们可以用int自然溢出最后答案&(2147483647) (就是2^31 -1 啦
Code:
#include<bits/stdc++.h> #define debug(x) cout<<#x<<"="<<x<<endl #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 using namespace std; typedef pair<int,int> List; const int maxn = 200009; const int uuz = 2147483647; int n,m; int first[maxn]; struct edg { int next; int to; }e[maxn<<1]; int e_sum; int fa[maxn],dep[maxn],son[maxn],siz[maxn],pos[maxn],top[maxn],L[maxn],R[maxn]; int cnt,ans; struct sg_tree{int sum,tag;}node[maxn<<2]; List chain[9]; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void add_edg(int x,int y) { e_sum++; e[e_sum].next=first[x]; first[x]=e_sum; e[e_sum].to=y; } void dfs1(int x,int f) { dep[x]=dep[f]+1;siz[x]=1;fa[x]=f; for(int i=first[x];i;i=e[i].next) { int w=e[i].to; if(w==f) continue; dfs1(w,x); siz[x]+=siz[w]; if(siz[w]>siz[son[x]]) son[x]=w; } } void dfs2(int x,int t) { top[x]=t;pos[x]=++cnt;L[x]=cnt; if(son[x]) dfs2(son[x],t); for(int i=first[x];i;i=e[i].next) { int w=e[i].to; if(w==fa[x]||w==son[x]) continue; dfs2(w,w); }R[x]=cnt; } void updata(int rt){node[rt].sum=node[rt<<1].sum+node[rt<<1|1].sum;} void make_plus(int l,int r,int rt,int delta) { node[rt].sum+=(r-l+1)*delta; node[rt].tag+=delta; } void down(int l,int r,int rt) { if(node[rt].tag) { int mid=(l+r)>>1; make_plus(lson,node[rt].tag); make_plus(rson,node[rt].tag); node[rt].tag=0; } } void modify(int l,int r,int rt,int left,int right,int delta) { if(l==left&&right==r) { make_plus(l,r,rt,delta); return ; }int mid=(l+r)>>1;down(l,r,rt); if(right<=mid) modify(lson,left,right,delta); else if(left>mid) modify(rson,left,right,delta); else modify(lson,left,mid,delta),modify(rson,mid+1,right,delta); updata(rt); } int query(int l,int r,int rt,int left,int right) { if(left<=l&&r<=right) return node[rt].sum; int mid=(l+r)>>1;down(l,r,rt); if(right<=mid) return query(lson,left,right); else if(left>mid) return query(rson,left,right); else return query(lson,left,mid)+query(rson,mid+1,right); } int lca(int x,int y) { while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); x=fa[top[x]]; } if(dep[x]<dep[y]) return x; return y; } int ask(int x,int y) { if(x<=0) return 0; int sum=0; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); sum+=query(1,n,1,pos[top[x]],pos[x]); x=fa[top[x]]; } if(dep[x]<dep[y]) swap(x,y); sum+=query(1,n,1,pos[y],pos[x]); return sum; } List calc(List x,List y) { if(x.first==0) return y; if(x.first==-1) return x; int anc=lca(x.second,y.second); if(dep[anc]<max(dep[x.first],dep[y.first])) return make_pair(-1,-1); if(dep[x.first]>dep[y.first]) return make_pair(x.first,anc); else return make_pair(y.first,anc); } void solve(int step,List now,int opt,int lim) { if(step==lim) { ans+=ask(now.first,now.second)*opt; return ; } solve(step+1,now,opt,lim); solve(step+1,calc(now,chain[step+1]),-opt,lim); } int main() { n=read(); for(int i=1;i<n;i++) { int x=read(),y=read(); add_edg(x,y);add_edg(y,x); } dfs1(1,0);dfs2(1,1);m=read(); while(m--) { int opt=read(); if(opt==0) { int x=read(),k=read(); modify(1,n,1,L[x],R[x],k); } else { int k=read();ans=0; for(int i=1;i<=k;i++) { int x=read(),y=read(); if(dep[x]>dep[y]) swap(x,y); chain[i]=make_pair(x,y); } solve(0,make_pair(0,0),-1,k); printf("%d\n",ans&uuz); } } return 0; }
相关文章推荐
- 【BZOJ3589】动态树 树链剖分+线段树
- BZOJ 3589 动态树 树链剖分+容斥原理
- bzoj3589 动态树
- bzoj3589 动态树
- 树链剖分 BZOJ3589 动态树
- bzoj3589 动态树
- 【bzoj3589】动态树 树链剖分+线段树
- 【BZOJ 3589】 动态树
- bzoj千题计划214:bzoj3589: 动态树
- BZOJ 3589 动态树 树链拆分+纳入和排除定理
- BZOJ3589 : 动态树
- bzoj3589 动态树
- 【BZOJ】3589 动态树 树链剖分+线段树
- [BZOJ3589]动态树(树链剖分)
- BZOJ 3589 动态树 树链剖分+容斥定理
- BZOJ3589: 动态树
- [BZOJ3589]动态树(树链剖分+dfs序+lca)
- bzoj 3589 动态树
- BZOJ 3589: 动态树 树链剖分线段树
- [动态树分治] BZOJ4012 [HNOI2015]开店