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

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 200010
#define ui unsigned int
#define inf ((ui)4294967295)
#define p31 2147483647
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{int x=0,f=1;char c=getchar();while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f;
}
int n,p[N],fa[N],deep[N],son[N],size[N],top[N],dfn[N],L[N<<2],R[N<<2],u[6],v[6],flag[6],k,cnt,t;
ui tree[N<<2],lazy[N<<2],ans;
struct data{int to,nxt;
}edge[N<<1];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void dfs1(int k)
{size[k]=1;for (int i=p[k];i;i=edge[i].nxt)if (edge[i].to!=fa[k]){fa[edge[i].to]=k;deep[edge[i].to]=deep[k]+1;dfs1(edge[i].to);size[k]+=size[edge[i].to];if (size[edge[i].to]>size[son[k]]) son[k]=edge[i].to;}
}
void dfs2(int k,int from)
{dfn[k]=++cnt;top[k]=from;if (son[k]) dfs2(son[k],from);for (int i=p[k];i;i=edge[i].nxt)if (edge[i].to!=fa[k]&&edge[i].to!=son[k]) dfs2(edge[i].to,edge[i].to);
}
void build(int k,int l,int r)
{L[k]=l,R[k]=r;if (l==r) return;int mid=l+r>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);
}
void up(int k){tree[k]=tree[k<<1]+tree[k<<1|1];}
void update(int k,ui x){tree[k]+=(R[k]-L[k]+1)*x,lazy[k]+=x;}
void down(int k){update(k<<1,lazy[k]),update(k<<1|1,lazy[k]),lazy[k]=0;}
void add(int k,int l,int r,ui x)
{if (L[k]==l&&R[k]==r){update(k,x);return;}if (lazy[k]) down(k);int mid=L[k]+R[k]>>1;if (r<=mid) add(k<<1,l,r,x);else if (l>mid) add(k<<1|1,l,r,x);else add(k<<1,l,mid,x),add(k<<1|1,mid+1,r,x);up(k);
}
ui query(int k,int l,int r)
{if (L[k]==l&&R[k]==r) return tree[k];if (lazy[k]) down(k);int mid=L[k]+R[k]>>1;if (r<=mid) return query(k<<1,l,r);else if (l>mid) return query(k<<1|1,l,r);else return query(k<<1,l,mid)+query(k<<1|1,mid+1,r);
}
ui sum(int x,int y)
{ui ans=0;while (top[x]!=top[y]){if (deep[top[x]]<deep[top[y]]) swap(x,y);ans+=query(1,dfn[top[x]],dfn[x]);x=fa[top[x]];}if (deep[x]<deep[y]) swap(x,y);ans+=query(1,dfn[y],dfn[x]);return ans;
}
int lca(int x,int y)
{while (top[x]!=top[y]){if (deep[top[x]]<deep[top[y]]) swap(x,y);x=fa[top[x]];}if (deep[x]<deep[y]) swap(x,y);return y;
}
bool in(int x,int y){return dfn[x]<=dfn[y]&&dfn[x]+size[x]-1>=dfn[y];}
void calc(int op)
{int x=0,y=0;for (int i=1;i<=k;i++)if (flag[i]){if (!x) x=u[i],y=v[i];else{int p=u[i],q=v[i];if (deep[x]>deep[p]) swap(x,p),swap(y,q);if (in(x,p)&&in(p,y)) x=p,y=lca(y,q);else return;}}if (x==0) return;else if (op>0) ans+=sum(x,y);else ans+=inf-sum(x,y)+1;
}
void dfs(int cur,int op)
{if (cur>k) {calc(op);return;}flag[cur]=1;dfs(cur+1,-op);flag[cur]=0;dfs(cur+1,op);
}
int main()
{
#ifndef ONLINE_JUDGEfreopen("bzoj3589.in","r",stdin);freopen("bzoj3589.out","w",stdout);const char LL[]="%I64d\n";
#elseconst char LL[]="%lld\n";
#endifn=read();for (int i=1;i<n;i++){int x=read(),y=read();addedge(x,y),addedge(y,x);}dfs1(1);dfs2(1,1);build(1,1,n);int m=read();while (m--){int op=read();if (op==0){int x=read(),y=read();add(1,dfn[x],dfn[x]+size[x]-1,y);}if (op==1) {k=read();ans=0;for (int i=1;i<=k;i++) u[i]=read(),v[i]=read();for (int i=1;i<=k;i++) if (dfn[u[i]]>dfn[v[i]]) swap(u[i],v[i]);dfs(1,-1);printf("%u\n",ans&p31);}}return 0;
}

转载于:https://www.cnblogs.com/Gloid/p/10289789.html

BZOJ3589 动态树(树链剖分+容斥原理)相关推荐

  1. CodeForces - 1437G Death DBMS(AC自动机fail树上树链剖分建线段树/暴跳fail)

    题目链接:点击查看 题目大意:给出 n 个模式串,每个模式串初始时的权值为 0,然后有 m 次操作: 1 i x:将第 i 个模式串的权值修改为 x 2 s:给出一个字符串 s,询问字符串 s 作为主 ...

  2. 个人赛C 柠檬树2--树链剖分+维护最值出现次数/LCA

    给一棵树,维护上面两点最短路径中结点的最大值及最大值出现次数 #include <stdio.h> #include<string.h> #include<algorit ...

  3. [LOJ3014][JOI 2019 Final]独特的城市——树的直径+长链剖分

    题目链接: [JOI 2019 Final]独特的城市 对于每个点,它的答案最大就是与它距离最远的点的距离. 而如果与它距离为$x$的点有大于等于两个,那么与它距离小于等于$x$的点都不会被计入答案. ...

  4. [十二省联考2019]春节十二响——长链剖分+堆

    题目链接: [十二省联考2019]春节十二响 可以发现每条链上的所有点都要放在不同的段里,那么最多只需要树的深度这么多段就够了. 因为这样可以保证每条链上的点可以放在不同的段中而且一个点放在这些段中一 ...

  5. 【高级数据结构】[SPOJ QTREE]树链剖分/动态树各一模板

    题目: 树链剖分: #include<cstdio> #include<cstring> #include<algorithm> using namespace s ...

  6. bzoj3589 动态树 求链并 容斥

    bzoj3589 动态树 链接 bzoj 思路 求链并. 发现只有最多5条链子,可以容斥. 链交求法:链顶是两条链顶深度大的那个,链底是两个链底的\(lca\) 如果链底深度小于链顶,就说明两条链没有 ...

  7. URAL1553 Caves and Tunnels 树链剖分 动态树

    URAL1553 维护一棵树,随时修改某个节点的权值,询问(x,y)路径上权值最大的点. 树是静态的,不过套动态树也能过,时限卡的严就得上树链剖分了. 还是那句话 splay的核心是splay(x) ...

  8. BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector

    题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...

  9. Tsinsen A1517. 动态树 树链剖分,线段树,子树操作

    题目 : http://www.tsinsen.com/A1517 A1517. 动态树 时间限制:3.0s   内存限制:1.0GB    总提交次数:227   AC次数:67   平均分:49. ...

最新文章

  1. html扩展名用于保存清单文件,HTML5 manifest ApplicationCache
  2. centos6.5安装zabbix3.4
  3. windbg查看SSDT表
  4. QT的QNetworkAccessManager类的使用
  5. 《算法竞赛入门经典》 习题4-5 IP网络(IP Networks,ACM、ICPC NEERC 2005,UVa1590)
  6. java开发项目实例_学java开发,项目经验最重要
  7. Python 圈精选文章
  8. 21SpringMvc_异步发送表单数据到Bean,并响应JSON文本返回(这篇可能是最重要的一篇了)...
  9. 用Python【批量】生产【电子奖状】的方法请查收!
  10. 关于英语单词记忆的总结
  11. “给在读研究生+未来要读研同学们的一封受益匪浅的信”(摘录+整合)
  12. LT8711UXE1,Type-C/DP1.2 转 HDMI2.0,内置HDCP,支持4k 60Hz向下兼容
  13. 高校计算机专业实践教学改革研究,民族高校计算机专业实践教学改革
  14. BRDF Explorer
  15. 昆明拟整治11类陋习 行人翻越隔离设施罚50元
  16. 研究团队开发AI系统,仅通过足迹来识别身份
  17. 感恩生命,永不放弃——学习力克胡哲
  18. php留言本在线制作,Flash+php+mysql简单留言本制作
  19. 忠魁互联头条SEO优化:字节跳动打造全新搜索引擎
  20. Coins(多重背包方案可行性dp + 优化)

热门文章

  1. WIF - claims-based identity
  2. Perlin Noise algorithms(备忘)
  3. C# 2.0 套接字编程实例初探
  4. Android笔记 Application对象的使用-数据传递以及内存泄漏问题
  5. linux下文件权限管理
  6. 如何在Linux(CentOS, Debian, Fedora和Ubuntu)上安装MyCLI
  7. php正则 与 js正则
  8. 关于JavaScript的变量和函数提升
  9. DebugDiagx检测内存泄露
  10. 原来国家的名字可以如此浪漫!(ZZ)