BZOJ 3127 [Usaco2013 Open]Yin and Yang(树点分治)
【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=3127
【题目大意】
给出一棵01边权树,求存在多少条路径,使得路径上0和1的数量相同,
并且在路劲中能找到至少一个中断点,使得分为两段01数量相同的路径
【题解】
我们对这棵树进行点分治,每次只考虑经过重心的路径,
我们将路径权值和分出现一次和出现多次进行统计,如果出现一次,
则在之前出现了多次的权值数组中查相反数,如果出现多次,
则是一次和多次的权值数组的和,权值和为0的特殊情况则另需考虑以重心为端点的路径。
每个子树先计算答案,然后统计入权值数组。
【代码】
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
const int N=200020;
vector<int> v[N],e[N];
typedef long long LL;
const int base=100010;
int n,cnt,root,sum,nowT=0;
int mark[N],T1[N],T2[N],size[N],d[N],dp[N],t[N],vis[N];
LL S1[N],S2[N],ans;
void getroot(int x,int fx){
size[x]=1; dp[x]=0;
for(int i=0;i<v[x].size();i++){
int y=v[x][i];
if(!vis[y]&&y!=fx){
getroot(y,x);
size[x]+=size[y];
dp[x]=max(dp[x],size[y]);
}
}dp[x]=max(dp[x],sum-size[x]);
if(dp[x]<dp[root])root=x;
}
void getdeep(int x,int fx){
if(mark[base+d[x]]){
mark[base+d[x]]++;
if(!d[x])ans++;
if(T2[base+d[x]]==root)S2[base+d[x]]++;
else T2[base+d[x]]=root,S2[base+d[x]]=1;
}else{
mark[base+d[x]]++;
if(T1[base+d[x]]==root)S1[base+d[x]]++;
else T1[base+d[x]]=root,S1[base+d[x]]=1;
}
for(int i=0;i<v[x].size();i++){
int y=v[x][i],w=e[x][i];
if(!vis[y]&&y!=fx){
d[y]=d[x]+w;
getdeep(y,x);
}
}mark[base+d[x]]--;
}
void caldeep(int x,int fx){
if(mark[base-d[x]]){
mark[base-d[x]]++;
if(T2[base-d[x]]==root)ans+=S2[base-d[x]];
else T2[base-d[x]]=root,S2[base-d[x]]=0;
if(T1[base-d[x]]==root)ans+=S1[base-d[x]];
else T1[base-d[x]]=root,S1[base-d[x]]=0;
}else{
mark[base-d[x]]++;
if(T2[base-d[x]]==root)ans+=S2[base-d[x]];
else T2[base-d[x]]=root,S2[base-d[x]]=0;
if(T1[base-d[x]]==root){
if(!d[x])ans+=S1[base-d[x]];
}else T1[base-d[x]]=root,S1[base-d[x]]=0;
}
for(int i=0;i<v[x].size();i++){
int y=v[x][i],w=e[x][i];
if(!vis[y]&&y!=fx){
d[y]=d[x]+w;
caldeep(y,x);
}
}mark[base-d[x]]--;
}
void cal(int x){
for(int i=0;i<v[x].size();i++){
int y=v[x][i],w=e[x][i];
if(!vis[y]){
d[y]=w;
caldeep(y,x);
getdeep(y,x);
}
}
}
void solve(int x){
cal(x); vis[x]=1;
for(int i=0;i<v[x].size();i++){
int y=v[x][i];
if(!vis[y]){
root=0;sum=size[y];
getroot(y,0);
solve(root);
}
}
}
int main(){
while(~scanf("%d",&n)){
ans=0;
for(int i=1;i<=n;i++)v[i].clear(),e[i].clear();
for(int i=1;i<n;i++){
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
v[x].push_back(y);
v[y].push_back(x);
e[x].push_back(w?1:-1);
e[y].push_back(w?1:-1);
}memset(vis,0,sizeof(vis));
dp[0]=sum=n;
getroot(1,0);
solve(root);
printf("%lld\n",ans);
}return 0;
}
BZOJ 3127 [Usaco2013 Open]Yin and Yang(树点分治)的更多相关文章
- bzoj3127/3697 [Usaco2013 Open]Yin and Yang
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3127 http://www.lydsy.com/JudgeOnline/problem.ph ...
- BZOJ 3939 [Usaco2015 Feb]Cow Hopscotch ——线段树 CDQ分治
显然dp[i][j]=ps[i-1][j-1]-sigma(dp[k<i][l<j],a[i][j]=a[k][l]) 考虑对于每一种颜色都开一颗区间线段树,但是空间不够. 所以我们可以动 ...
- 洛谷P3085 [USACO13OPEN]阴和阳Yin and Yang(点分治,树上差分)
洛谷题目传送门 闲话 偶然翻到一道没有题解的淀粉质,想证明一下自己是真的弱 然而ZSYC(字符串组合)早就切了 然后证明成功了,WA到怀疑人生,只好借着ZSY的代码拍,拍了几万组就出来了... 思路 ...
- BZOJ.3653.谈笑风生(长链剖分/线段树合并/树状数组)
BZOJ 洛谷 \(Description\) 给定一棵树,每次询问给定\(p,k\),求满足\(p,a\)都是\(b\)的祖先,且\(p,a\)距离不超过\(k\)的三元组\(p,a,b\)个数. ...
- BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )
BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...
- 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护
线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...
- bzoj 4031: 小Z的房间 矩阵树定理
bzoj 4031: 小Z的房间 矩阵树定理 题目: 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时 ...
- [bzoj 3048] [Usaco2013 Jan]Cow Lineup
[bzoj 3048] [Usaco2013 Jan]Cow Lineup Description 给你一个长度为n(1<=n<=100,000)的自然数数列,其中每一个数都小于等于10亿 ...
- [BZOJ 1535] [Luogu 3426]SZA-Template (KMP+fail树+双向链表)
[BZOJ 1535] [Luogu 3426]SZA-Template (KMP+fail树+双向链表) 题面 Byteasar 想在墙上涂一段很长的字符,他为了做这件事从字符的前面一段中截取了一段 ...
随机推荐
- 炒鸡简单的canvas粒子(山东数漫江湖)
位图的canvas一直不会被svg比下去的原因了. 俗话说,须弥芥子,是大小之说,也有以小见大之说,颗颗粒子,足以构建宏大效果. 这是一篇炒鸡简单的canvas粒子教程,主要是讲如何粒子特效的原理,一 ...
- Spring Data JPA 的使用(山东数漫江湖)
pring data jpa介绍 什么是JPA JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关联映射工具来管理Java应 ...
- bzoj 2121 DP
首先如果我们能处理出来i,j段能不能消掉,这样就可以直接dp转移了,设w[i]为前i为最少剩下多少,那么w[i]=w[j-1] (flag[j][i]). 现在我们来求flag[i][j],首先我们可 ...
- Eclipse连接海马模拟器
找到海马模拟器安装目录: 使用cmd 命令进入命令行:D: cd:D:\Program Files (x86)\Droid4X 进入模拟器所在目录 运行adb connect 127.0.0.1:26 ...
- Linux系统编程——进程间通信(一)
基本操作命令: ps -ajx/-aux/-ef 查看进程间状态/的相互关系 top 动态显示系统中的进程 nice 按照指定的优先级运行 /renice 改变正在运行的进程的优先级 kill -9杀 ...
- JQuery实现AJAX实例
<script type="text/javascript" src="ReportServer?op=emb&resource=finereport.js ...
- Nginx web proxy NFS服务
1.nginx web 安装 配置 #systemctl stop firewalld #systemctl disabled firewalld #wget -O /etc/yum.repos.d/ ...
- 一个大div里面包裹一个小div,里面的小div的点击事件不触发外面的这个大div的点击事件
一开始上html代码 <div id="div1" style="background: blue;width: 100px; height: 100px;&quo ...
- Rotate Image——数学相关
You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). ...
- Windows7 + OSG3.6 + VS2017 + Qt5.11
一.准备工作 下载需要的材料: 1. OSG稳定版源代码, 3.6.3版本 2. 第三方库,选择VS2017对应的版本 https://download.osgvisual.org/3rdParty ...