题目描述

在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 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. Oracle官网下载参考文档

    最近有人问我有没有Oracle11g数据库官方参考文档,我就想,这不是在官网可以下载到的吗,疑惑,问了之后才知道,他官网找过,但时没有找到.不要笑,其实有很多人一样是找不到的,下面就一步一步操作下: ...

  2. java性能监控工具jstat

    jstat Monitors Java Virtual Machine (JVM) statistics. This command is experimental and unsupported. ...

  3. BAT技术需求,你能达到多少?

    作为中国互联网界的传奇和标杆企业,BAT 三家公司的一举一动受互联网人的精密亲密关注.进入 BAT 成为大厂的一员成了许多互联网人职业生活生存追逐的方针之一. 本文的作者作为一个非科班毕业,出身于三流 ...

  4. 使用springcloud gateway搭建网关(分流,限流,熔断)

    Spring Cloud Gateway Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 ...

  5. springboot面试专题及答案

    声明:此文章非本人所 原创,是别人分享所得,如有知道原作者是谁可以联系本人,如有转载请加上此段话 问题一 什么是 Spring Boot? 多年来,随着新功能的增加,spring 变得越来越复杂.只需 ...

  6. java 之DelayQueue实际运用示例

    在学习Java 多线程并发开发过程中,了解到DelayQueue类的主要作用:是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走. ...

  7. package.json参数简单介绍

    概述: 每个项目的根目录下都会有一个package.json文件,定义了项目所需的模块,以及项目信息.执行npm install 命令会自动下载package.json中配置的模块,也就是配置项目的运 ...

  8. vue-router 路由懒加载

    webpack打包会将所有资源文件合并压缩成一个文件,导致最终的文件非常大,甚至超过几M,以致页面首次加载会比较慢,如下图: 其中红色标出的是在浏览器中加载的js文件,gzip压缩前已经达到500多K ...

  9. pair

    pair的类型: pair 是 一种模版类型.每个pair 可以存储两个值.这两种值无限制.也可以将自己写的struct的对象放进去.. 功能:pair将一对值组合成一个值,这一对值可以具有不同的数据 ...

  10. e.stopPropagation()

    1. 定义和用法 不再派发事件. 终止事件在传播过程的捕获.目标处理或起泡阶段进一步传播.调用该方法后,该节点上处理该事件的处理程序将被调用,事件不再被分派到其他节点. 2. 语法 event.sto ...