题意:给你一棵树,要求你维护两个操作.

0:某子树的所有节点权值加上一个数.

1:求某些链并集的权值和.

对于第一个操作,大力树链剖分加线段树.

对于第二个操作,考虑到链的数量很少,可以容斥.

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iomanip>
using namespace std;
#define LL long long
#define up(i,j,n) for(int i=j;i<=n;i++)
#define pii pair<int,int>
#define db double
#define eps 1e-4
#define FILE "dealing"
int read(){int x=0,f=1,ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0',ch=getchar();}return x*f;
}
const LL maxn=1000000,inf=1000000000000000LL,limit=20000;
bool cmin(int& a,int b){return a>b?a=b,true:false;}
bool cmax(int& a,int b){return a<b?a=b,true:false;}
int n,m;
struct node{int y,next;
}e[maxn];
int len=0,linkk[maxn],top[maxn],fa[maxn],dep[maxn],pre[maxn],low[maxn];
void insert(int x,int y){e[++len].y=y;e[len].next=linkk[x];linkk[x]=len;
}
void init(){n=read();up(i,1,n-1){int x=read(),y=read();insert(x,y);insert(y,x);}
}
namespace treepou{int dfs_clock=0,siz[maxn],son[maxn];void dfs1(int x){siz[x]=1;for(int i=linkk[x];i;i=e[i].next){if(e[i].y==fa[x])continue;fa[e[i].y]=x;dep[e[i].y]=dep[x]+1;dfs1(e[i].y);siz[x]+=siz[e[i].y];if(siz[e[i].y]>siz[son[x]])son[x]=e[i].y;}}void dfs2(int x){pre[x]=++dfs_clock;if(son[x]){top[son[x]]=top[x];dfs2(son[x]);}for(int i=linkk[x];i;i=e[i].next){if(e[i].y==son[x]||e[i].y==fa[x])continue;top[e[i].y]=e[i].y;dfs2(e[i].y);}low[x]=dfs_clock;}void solve(){dfs1(1);top[1]=1;dfs2(1);}
};
namespace SegTree{int del[maxn],siz[maxn],sum[maxn],L,R,key,id[maxn];int Add(int x,int d){del[x]+=d;sum[x]+=siz[x]*d;}void updata(int x){sum[x]=sum[x<<1]+sum[x<<1|1];}void pushdown(int x){if(del[x]){Add(x<<1,del[x]);Add(x<<1|1,del[x]);del[x]=0;}}void change(int o,int l,int r){if(l>R||r<L)return;if(l>=L&&r<=R){Add(o,key);return;}int mid=(l+r)>>1;pushdown(o);change(o<<1,l,mid);change(o<<1|1,mid+1,r);updata(o);}void Change(int x,int y,int Del){L=x,R=y,key=Del;change(1,1,n);}int query(int l,int r,int o){if(l>R||r<L)return 0;if(l>=L&&r<=R)return sum[o];int mid=(l+r)>>1;pushdown(o);return query(l,mid,o<<1)+query(mid+1,r,o<<1|1);}int Query(int x,int y){if(x>y)swap(x,y);L=x,R=y;return query(1,n,1);}void build(int l,int r,int o){if(l==r){siz[o]=1;sum[o]=0;return;}int mid=(l+r)>>1;build(l,mid,o<<1);build(mid+1,r,o<<1|1);siz[o]=siz[o<<1]+siz[o<<1|1];}void Build(){up(i,1,n)id[pre[i]]=i;build(1,n,1);}
}
namespace solve{pii getlian(int x,int y){int f1,f2;int sum=0;while(true){if(dep[x]>dep[y])swap(x,y);f1=top[x],f2=top[y];if(f1==f2){sum+=SegTree::Query(pre[x],pre[y]);return make_pair(x,sum);}if(dep[f1]>dep[f2])swap(x,y),swap(f1,f2);sum+=SegTree::Query(pre[f2],pre[y]);y=fa[f2];}}int getlca(int x,int y){int f1,f2;while(true){if(dep[x]>dep[y])swap(x,y);f1=top[x],f2=top[y];if(f1==f2)return x;if(dep[f1]>dep[f2])swap(x,y),swap(f1,f2);y=fa[f2];}}pii t[maxn];int query(){int m=read();up(i,1,m){t[i].first=read(),t[i].second=read();if(dep[t[i].first]>dep[t[i].second])swap(t[i].first,t[i].second);}pii y=make_pair(0,0);int ans=0;for(int i=1;i<(1<<m);i++){int g=-1,flag=0;up(j,1,m){if(i&(1<<j-1))g*=-1;else continue;if(!flag)y=t[j],flag=1;else {int w=getlca(y.second,t[j].second);if(dep[w]<dep[y.first]||dep[w]<dep[t[j].first]){y=make_pair(0,0);break;}else {if(dep[y.first]<dep[t[j].first])y.first=t[j].first;y.second=w;}}}//printf("%d %d %d\n",g,y.first,y.second);if(y.first)ans+=g*getlian(y.first,y.second).second;}return ans;}
};int main(){freopen(FILE".in","r",stdin);freopen(FILE".out","w",stdout);init();treepou::solve();//树剖 返回top,dep,faSegTree::Build();//prepare SegTree int m=read();while(m--){int ch=read();if(ch==0){int x=read(),del=read();SegTree::Change(pre[x],low[x],del);}else printf("%d\n",solve::query()&((1<<31)-1));}return 0;
}

  

转载于:https://www.cnblogs.com/chadinblog/p/6492672.html

bzoj3589 动态树相关推荐

  1. bzoj3589 动态树 求链并 容斥

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

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

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

  3. 如何利用FineReport制作动态树报表

    在对数据字段进行分类管理时,利用动态树折叠数据是一个很好的方法,也就是点击数据前面的加号才展开对应下面的数据,如下图.那这样的效果在制作报表时该如何实现呢? 下面以报表工具FineReport为例介绍 ...

  4. 【动态树】[BZOJ2002] Bounce 弹飞绵羊

    实际上就是动态树的模版加上一个维护每一条链的size这样就可以吧一次弹射看成一条路径,然后统计这个路径上的size实际上就是经过了多少个节点然后没什么了.. #include <bits/std ...

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

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

  6. 动态树与静态树显示——(一)

    常用属性 常用事件: 1.第一种是静态树: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> ...

  7. P4719 【模板】“动态 DP“动态树分治(矩阵/轻重链剖分/ddp)

    P4719 [模板]"动态 DP"&动态树分治 求解树上最大权独立集,但是需要支持修改. https://www.luogu.com.cn/problem/solution ...

  8. luoguP3690 【模板】Link Cut Tree (动态树)[LCT]

    题目背景 动态树 题目描述 给定N个点以及每个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor ...

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

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

最新文章

  1. ACL 2019 | 基于知识增强的语言表示模型,多项NLP任务表现超越BERT(附论文解读)...
  2. 博士申请 | 加拿大麦吉尔大学丁俊老师招收机器学习全奖博士/硕士/实习生
  3. 全自动洗衣机单片机c语言程序,全自动洗衣机单片机程序
  4. python函数星号参数
  5. mysql数据库管理系统模式_MYSQL命令行模式管理MySql的一点心得
  6. js 获取url问号前_收下这波 JS 技巧,从此少加班
  7. Microsoft Enterprise Library 5.0 系列教程(二) Cryptography Application Block (初级)
  8. Spring Cloud微服务之Hystrix服务熔断(十二)
  9. 福大软工1816 · 第二次作业 - 个人项目
  10. Vue2.x中的父组件数据传递至子组件
  11. git整合分支的两种方式 merge 和 rebase
  12. AcWing 1208. 翻硬币
  13. Git 学习笔记--git 查看某个文件的修改历史
  14. Json转换为Model,Struct,Class对象 Swift
  15. 动网论坛 php版,动网即将推出第二代PHP版本论坛系统
  16. linux下文本去重
  17. vue+echarts绘制中国地图,动态配置省份颜色和城市标点
  18. MATLAB全局变量
  19. CSS 实现元素固定宽高比
  20. SQL求连续活跃天数

热门文章

  1. 概率论与数理统计(一)
  2. CTFshow 文件上传 web155
  3. CTFshow 命令执行 web30
  4. tkinter绑定鼠标滚轮滚动事件
  5. Python 基础语法(一)
  6. Python基础10 反过头来看看
  7. 详解JavaScript中ES5和ES6的类、继承之间区别和联系
  8. 计算机网络与通信这门课难不难,【知乎】计算机网络这门课为何如此之难
  9. linux sybase系统,linux sybase 安装全过程(写给初学者)
  10. CMD查询Mysql中文乱码的解决方法