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 想在墙上涂一段很长的字符,他为了做这件事从字符的前面一段中截取了一段 ...
随机推荐
- nsa工程式(fb.py): perl6调用并修改IP
use v6; if (@*ARGS != 1) {say 'Use:scan.p6 ip';exit;} my $check_ip = @*ARGS[0]; $check_ip = '<val ...
- 从零开始PHP攻略(001)——Bob的汽车零部件商店
1.创建订单表单 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...
- Pythone3 sys模块
1.sys.argv 可以实现从程序外部向程序传递参数2.sys.exit() 程序中间退出,exit(0)正常退出,其他为异常退出3.sys.getdefaultencoding() 获取系统编码方 ...
- TCP之非阻塞connect和accept
套接字的默认状态是阻塞的,这就意味着当发出一个不能立即完成的套接字调用时,其进程将被投入睡眠,等待响应操作完成,可能阻塞的套接字调用可分为以下四类: (1) 输入操作,包括read,readv,rec ...
- shell中的IFS和$*变量
本文转载自http://blog.chinaunix.net/uid-22566367-id-381955.html 自我记录内容.在工程中遇到了相关内容的shell脚本.在此处记录 STRING1= ...
- 工具安装===Sublime Text-安装
Sublime Text 是一款通用型轻量级编辑器,支持多种编程语言.有许多功能强大的快捷键(如 Ctrl+d),支持丰富的插件扩展.如果平时需要在不同编程语言间切换,那么它将会是一个,不错的选择. ...
- UVA 11076 Add Again
题目链接:UVA-33478 题意为给定n个数,求这n个数能组成的所有不同的排列组成的数字的和. 思路:发现对于任意一个数字,其在每一位出现的次数是相同的.换言之,所有数字的每一位相加的和是相同的. ...
- Load balancer does not have available server for client:xxx
今天在搭建一个springcloud项目在搭建以zuul为网关的时候,项目抛了一个异常, com.netflix.zuul.exception.ZuulException: Forwarding er ...
- 获取分组后的TOP 1和TOP N记录
MySQL获取分组后的TOP 1和TOP N记录 有时会碰到一些需求,查询分组后的最大值,最小值所在的整行记录或者分组后的top n行的记录,在一些别的数据库可能有窗口函数可以方面的查出来,但是MyS ...
- PHP设计模式二-------单例模式
1.单例模式的介绍 意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点: 主要解决:一个全局使用的类频繁地创建与销毁. 关键代码:构造函数是私有的,克隆方法也是私有的. 1.1 懒汉式//1 ...