bzoj3589 动态树

链接

bzoj

思路

求链并。
发现只有最多5条链子,可以容斥。
链交求法:链顶是两条链顶深度大的那个,链底是两个链底的\(lca\)
如果链底深度小于链顶,就说明两条链没有交集。
复杂度\(m*2^klog^2n\)
还有一种做法。
把所有链子都打上\(0/1tag\),只有\(1\)才能有贡献。
应该挺麻烦的,或者说都挺好写的。

代码

#include <bits/stdc++.h>
using namespace std;
const int _=4e5+7;
int read() {int x=0,f=1;char s=getchar();for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';return x*f;
}
int n,Q,S[6],T[6];
struct node {int v,nxt;}e[_<<1];
int head[_],tot;
void add(int u,int v) {e[++tot].v=v;e[tot].nxt=head[u];head[u]=tot;
}
namespace seg {#define ls rt<<1#define rs rt<<1|1struct node {int l,r,siz,tot,lazy;}e[_<<2];void build(int l,int r,int rt) {e[rt].l=l,e[rt].r=r,e[rt].siz=r-l+1;if(l==r) return;int mid=(l+r)>>1;build(l,mid,ls);build(mid+1,r,rs);}void pushdown(int rt) {if(e[rt].lazy) {e[ls].tot+=e[ls].siz*e[rt].lazy;e[rs].tot+=e[rs].siz*e[rt].lazy;e[ls].lazy+=e[rt].lazy;e[rs].lazy+=e[rt].lazy;e[rt].lazy=0;}}void modify(int L,int R,int ad,int rt) {if(L<=e[rt].l&&e[rt].r<=R) {e[rt].tot+=e[rt].siz*ad;e[rt].lazy+=ad;return;}int mid=(e[rt].l+e[rt].r)>>1;pushdown(rt);if(L<=mid) modify(L,R,ad,ls);if(R>mid) modify(L,R,ad,rs);e[rt].tot=e[ls].tot+e[rs].tot;}int query(int L,int R,int rt) {if(L<=e[rt].l&&e[rt].r<=R) return e[rt].tot;int mid=(e[rt].l+e[rt].r)>>1,ans=0;pushdown(rt);if(L<=mid) ans+=query(L,R,ls);if(R>mid) ans+=query(L,R,rs);return ans;}
}
int dep[_],f[_],siz[_],son[_],top[_],idx[_],cnt;
void dfs1(int u,int fa) {dep[u]=dep[fa]+1;siz[u]=1;f[u]=fa;for(int i=head[u];i;i=e[i].nxt) {int v=e[i].v;if(v==fa) continue;dfs1(v,u);siz[u]+=siz[v];if(siz[v]>siz[son[u]]) son[u]=v;}
}
void dfs2(int u,int topf) {idx[u]=++cnt;top[u]=topf;if(!son[u]) return;dfs2(son[u],topf);for(int i=head[u];i;i=e[i].nxt) {int v=e[i].v;if(!idx[v]) dfs2(v,v);}
}
int LCA(int x,int y) {while(top[x]!=top[y]) {if(dep[top[x]]<dep[top[y]]) swap(x,y);x=f[top[x]];} if(dep[x]>dep[y]) swap(x,y);return x;
}
int QQ(int x,int y) {int tot=0;while(top[x]!=top[y]) {if(dep[top[x]]<dep[top[y]]) swap(x,y);tot+=seg::query(idx[top[x]],idx[x],1);x=f[top[x]];}if(dep[x]>dep[y]) swap(x,y);tot+=seg::query(idx[x],idx[y],1);return tot;
}
void dsrrr(int &a,int &b,int x,int y) {a=dep[a]>dep[x]?a:x,b=LCA(b,y);if(dep[b]<dep[a]) a=-1,b=-1;
}
int calc(int x) {int s=0,t=0;for(int i=1;x;i++,x>>=1) {if(x&1) {if(!s&&!t) s=S[i],t=T[i];else dsrrr(s,t,S[i],T[i]);} if(s==-1&&t==-1) return 0;}return QQ(s,t);
}
int man[40];
int main() {n=read();for(int i=1,u,v;i<n;++i) {u=read(),v=read();add(u,v),add(v,u);}seg::build(1,n,1);dfs1(1,0),dfs2(1,1);Q=read();for(int i=1;i<(1<<5);++i)for(int j=0;j<5;++j)if(i&(1<<j)) man[i]++;while (Q --> 0) {int opt=read();if(!opt) {int u=read(),val=read();seg::modify(idx[u],idx[u]+siz[u]-1,val,1);} else {int k=read();for(int i=1;i<=k;++i) {S[i]=read(),T[i]=read();if(dep[S[i]]>dep[T[i]]) swap(S[i],T[i]);}int ans=0;for(int i=1;i<(1<<k);++i)ans+=(man[i]&1?1:-1)*calc(i);printf("%d\n",ans&2147483647);}}return 0;
}

转载于:https://www.cnblogs.com/dsrdsr/p/11405973.html

bzoj3589 动态树 求链并 容斥相关推荐

  1. BZOJ3589 动态树(树链剖分+容斥原理)

    显然容斥后转化为求树链的交.这个题非常良心的保证了查询的路径都是到祖先的,求交就很休闲了. #include<iostream> #include<cstdio> #inclu ...

  2. bzoj3589 动态树

    题意:给你一棵树,要求你维护两个操作. 0:某子树的所有节点权值加上一个数. 1:求某些链并集的权值和. 对于第一个操作,大力树链剖分加线段树. 对于第二个操作,考虑到链的数量很少,可以容斥. 代码: ...

  3. 小奇遐想 树状数组实现+容斥思想

    问题 M: 小奇遐想 时间限制: 1 Sec  内存限制: 128 MB 提交: 165  解决: 21 [提交] [状态] [讨论版] [命题人:admin] 题目描述 撷来一缕清风飘渺 方知今日书 ...

  4. Wannafly挑战赛19:C. 多彩的树(状压+容斥)

    链接:https://www.nowcoder.com/acm/contest/131/C 来源:牛客网 题目描述 有一棵树包含 N 个节点,节点编号从 1 到 N.节点总共有 K 种颜色,颜色编号从 ...

  5. loj#2542 [PKUWC2018]随机游走 (概率期望、组合数学、子集和变换、Min-Max容斥)

    loj#2542 [PKUWC2018]随机游走 (概率期望.组合数学.子集和变换.Min-Max容斥) 很好很有趣很神仙的题! 题目链接: https://loj.ac/problem/2542 题 ...

  6. LOJ #2542 [PKUWC2018]随机游走 (概率期望、组合数学、子集和变换、Min-Max容斥)

    很好很有趣很神仙的题! 题目链接: https://loj.ac/problem/2542 题意: 请自行阅读 题解首先我们显然要求的是几个随机变量的最大值的期望(不是期望的最大值),然后这玩意很难求 ...

  7. 【DP】【容斥】Nice to Meet You(AT3634)

    正题 luogu AT3634 题目大意 给你一个图,让你给图上的边定方向,问1,2两个点可以到同一个点的方案数 解题思路 直接求可以到同一个点不好求,可以用总方案数减去不合法方案数,即到不了同一个点 ...

  8. CodeForces 1139D Steps to One(概率dp 容斥/莫比乌斯反演)

    题目链接https://codeforces.com/contest/1139/problem/D 题意:给定一个m,每次在1-m中随机取一个数放到容器中,当容器的gcd为1时停止,求期望步数,用分数 ...

  9. HDU - 7009 树上游走(树的直径+容斥)

    题目链接:点击查看 题目大意:给一棵树,称一个点集 S 是好的当且仅当存在一个点,其到 S 中所有点的距离互不相同,求 |S| 的最大值和使得 |S| 最大的 S 的个数 题目分析:不难看出 ∣S∣| ...

最新文章

  1. 编译linux内核时出错
  2. ChartCtrl源码剖析之——CChartAxis类
  3. Android之应用程序如何调用支付宝接口
  4. java comparator相等_详解Java中Comparable和Comparator接口的区别
  5. 【C++ Priemr | 15】派生类向基类转换的可访问性
  6. wince bib文件合成
  7. python 数字转化excel行列_Python实现excel的列名称转数字、26进制(A-Z)与10进制互相转换...
  8. 斐波那契数列(信息学奥赛一本通-T1159)
  9. ActiveMQ Destination高级特性
  10. 零成本兼职副业有哪些?
  11. 读取配置文件(configparser,.ini文件)
  12. 使用frp实现将内网映射到公网 无需花生壳
  13. 洛谷 P2294 [HNOI2005]狡猾的商人
  14. 利用JS获取用户当前ip地址
  15. 计算机ip地址会变吗,电脑IP地址会变吗?
  16. ActiveMQ--CVE-2015-5254
  17. HIBOX/OPENBOX接收JBS、蜻蜓的遥控器设置
  18. HDU 2154 跳舞毯
  19. 78 网站点击流数据分析案例(网站流量分析过程)
  20. 如何监控前端页面FPS

热门文章

  1. qnap nas web php,如何在QNAP NAS上建立并使用 iSCSI Target
  2. java 运行 .jar 文件乱码
  3. set和enum类型的用法和区别
  4. 再论EM算法的收敛性和K-Means的收敛性
  5. 设计之路:如何进行软件需求分析?
  6. 用maven运行指定java类main方法
  7. sql查询结果字段名与字段值倒过来了
  8. seleniumpython定位网页元素方法_使用Selenium对网页元素进行定位的诸种方法
  9. matplotlib  plt.scatter
  10. ubuntu ls命令