题目描述

在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当这条路径上的工业城市和农业城市数目相等。现在国王想把城市分给他的两个儿子,大儿子想知道,他选择一段标号连续的城市作为自己的领地,并把剩下的给弟弟,能够满足两端都是自己城市的 exciting 路径比两端都是弟弟的城市的 exciting 路径数目多的方案数。

输入格式

第一行一个正整数 n n n。
第二行 n n n 个整数依次描述城市的性质,1 1 1 为工业,0 0 0 为农业。
接下来 n−1 n - 1 n−1 行每行两个正整数描述一条道路。

输出格式

输出一个整数表示答案。

样例

样例输入

5
1 0 1 0 1
1 2
1 3
2 4
2 5

样例输出

5

数据范围与提示

n≤100000 n \leq 100000 n≤100000

正解:点分治。

对于每个右端点,我们找出极小的左端点使得在这个区间内大儿子不能获利,显然这是满足单调性的。

然后我们设$A$为两个端点都在区间内的路径数量,$B$为两个端点都在区间外的路径数量,如果$A>B$,那么左端点就可以往右移。

设$C$为两个端点分别在区间内外的答案,我们发现$2A+C>2B+C$与前面的不等式是等价的。

设$sum$为总路径数$*2$,$f[i]$为一个端点为$i$的路径数量,那么$2A+C=\sum_{i=l}^{r}f[i]$,$2B+C=sum-\sum_{i=l}^{r}f[i]$。

然后用点分治来统计一下路径就行了。。

 #include <bits/stdc++.h>
#define il inline
#define RG register
#define ll long long
#define N (500005) using namespace std; struct edge{ int nt,to; }g[N];
struct data{ int i,l; }st[N]; int head[N],tong[N],vis[N],dis[N],son[N],sz[N],a[N],n,num,top;
ll f[N],now,sum,ans; il int gi(){
RG int x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return q*x;
} il void insert(RG int from,RG int to){
g[++num]=(edge){head[from],to},head[from]=num; return;
} il void getrt(RG int x,RG int p,RG int &rt){
son[x]=,sz[x]=;
for (RG int i=head[x],v;i;i=g[i].nt){
v=g[i].to; if (v==p || vis[v]) continue;
getrt(v,x,rt),sz[x]+=sz[v],son[x]=max(son[x],sz[v]);
}
son[x]=max(son[x],son[]-sz[x]);
if (son[rt]>=son[x]) rt=x; return;
} il void getdis(RG int x,RG int p){
dis[x]=dis[p]+a[x],st[++top]=(data){x,dis[x]},sz[x]=;
for (RG int i=head[x],v;i;i=g[i].nt){
v=g[i].to; if (v==p || vis[v]) continue;
getdis(v,x),sz[x]+=sz[v];
}
return;
} il void calc(RG int rt,RG int p,RG int fg){
top=,getdis(rt,p);
for (RG int i=;i<=top;++i) ++tong[n+st[i].l];
for (RG int i=,res;i<=top;++i)
res=fg*tong[n+(p?a[p]:a[rt])-st[i].l],sum+=res,f[st[i].i]+=res;
for (RG int i=;i<=top;++i) --tong[n+st[i].l]; return;
} il void solve(RG int x,RG int S){
RG int rt=; son[]=S,getrt(x,,rt);
vis[rt]=,dis[rt]=a[rt],calc(rt,,);
for (RG int i=head[rt];i;i=g[i].nt)
if (!vis[g[i].to]) calc(g[i].to,rt,-);
for (RG int i=head[rt];i;i=g[i].nt)
if (!vis[g[i].to]) solve(g[i].to,sz[g[i].to]);
return;
} int main(){
#ifndef ONLINE_JUDGE
freopen("king.in","r",stdin);
freopen("king.out","w",stdout);
#endif
n=gi();
for (RG int i=;i<=n;++i) a[i]=gi()?:-;
for (RG int i=,u,v;i<n;++i)
u=gi(),v=gi(),insert(u,v),insert(v,u);
solve(,n);
for (RG int i=,j=;i<=n;++i){
now+=f[i]; while (j<=i && now<<>sum) now-=f[j++];
ans+=j-;
}
cout<<ans; return ;
}

loj6119 「2017 山东二轮集训 Day7」国王的更多相关文章

  1. LOJ #6119. 「2017 山东二轮集训 Day7」国王

    Description 在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当 ...

  2. 【LOJ6077】「2017 山东一轮集训 Day7」逆序对 生成函数+组合数+DP

    [LOJ6077]「2017 山东一轮集训 Day7」逆序对 题目描述 给定 n,k ,请求出长度为 n的逆序对数恰好为 k 的排列的个数.答案对 109+7 取模. 对于一个长度为 n 的排列 p ...

  3. loj #6077. 「2017 山东一轮集训 Day7」逆序对

    #6077. 「2017 山东一轮集训 Day7」逆序对   题目描述 给定 n,k n, kn,k,请求出长度为 n nn 的逆序对数恰好为 k kk 的排列的个数.答案对 109+7 10 ^ 9 ...

  4. 题解 「2017 山东一轮集训 Day7」逆序对

    题目传送门 Description 给定 $ n, k $,请求出长度为 $ n $ 的逆序对数恰好为 $ k $ 的排列的个数.答案对 $ 10 ^ 9 + 7 $ 取模. 对于一个长度为 $ n ...

  5. 「2017 山东一轮集训 Day7」逆序对

    题解: 满满的套路题.. 首先显然从大到小枚举 然后每次生成的逆序对是1----(i-1)的 这样做dp是nk的 复杂度太高了 那我们转化一下问题 变成sigma(ai   (ai<i)  )= ...

  6. loj6102 「2017 山东二轮集训 Day1」第三题

    传送门:https://loj.ac/problem/6102 [题解] 贴一份zyz在知乎的回答吧 https://www.zhihu.com/question/61218881 其实是经典问题 # ...

  7. loj6100 「2017 山东二轮集训 Day1」第一题

    传送门:https://loj.ac/problem/6100 [题解] 我们考虑维护从某个端点开始的最长满足条件的长度,如果知道了这个东西显然我们可以用主席树来对每个节点建棵关于右端点的权值线段树, ...

  8. loj #6079. 「2017 山东一轮集训 Day7」养猫【最大费用最大流】

    首先假设全睡觉,然后用费用流考虑平衡要求建立网络流 把1~n的点看作是i-k+1~k这一段的和,连接(i,i+k,1,e[i]-s[i]),表示把i改成吃饭,能对i~i+k-1这一段的点产生影响:然后 ...

  9. LOJ6102「2017 山东二轮集训 Day1」第三题 【min-max容斥,反演】

    题目描述:输入一个大小为\(n\)的集合\(S\),求\(\text{lcm}_{k\in S}f_k\),其中\(f_k\)是第$$个Fibonacci数. 数据范围:\(n\le 5\times ...

随机推荐

  1. jquery select change下拉框选项变化判断选中值

    <th class="formTitle"> 是否转出: </th> <td class="formValue" colspan= ...

  2. 使用C#利用cmd来调用java jar包获取其中的数据

    其实也很简单,就是在C#中构建一个Process,启动jar包,并且给jar包传递参数 因为我并没有怎么学过JAVA,所以只写了个很小的Demo,就是根据传入的参数获取对应的数据 以下是JAVA De ...

  3. 百度AI人脸识别的学习总结

    本文主要分以下几个模块进行总结分析 项目要求:运用百度AI(人脸识别)通过本地与外网之间的信息交互(MQService),从而通过刷脸实现登陆.签字.会议签到等: 1.准备工作: 内网:单击事件按钮— ...

  4. Spring Security 安全框架

    一 简介:Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spr ...

  5. spring boot入门笔记 (三) - banner、热部署、命令行参数

    1.一般项目启动的时候,刚开始都有一个<spring>的标志,如何修改呢?在resources下面添加一个banner.txt就行了,springboot会自动给你加载banner.txt ...

  6. IOS微信后台运行时候倒计时暂停问题

    链接:https://pan.baidu.com/s/1i7cSkqL 密码:g80i 最近给央视做了个H5答题游戏,但在倒计时上遇到一个终端问题:手机端按Home键将微信收入后台之后,IOS11 会 ...

  7. Myeclipse打war包方法

    Myeclipse三种打包方法第一种方法打开Myeclipse如图操作. 如果该项目已存在需要移除之后在进行第三步,接着往下走. 项目打war包成功,推荐使用第一种方法. 第二种方法https://b ...

  8. CSS选择器之伪类选择器(伪元素)

    selection [CSS4]应用于文档中被用户高亮的部分(比如使用鼠标或其他选择设备选中的部分).(IE8及以下不支持)(火狐-moz-selection) first-line 选择每个 < ...

  9. 重要BLOG

    Cloud http://www.cnblogs.com/CloudMan6/tag/OpenStack/ 算法基础 http://www.cnblogs.com/ECJTUACM-873284962 ...

  10. solidity 语法学习

    基于 cryptozombies.io ZombieFactory pragma solidity ^0.4.19; contract ZombieFactory { // 事件, web3.js 可 ...