2017 山东二轮集训 Day7 国王

题目大意

给定一棵树,每个点有黑白两种颜色,定义一条简单路径合法当且仅当路径上所有点黑色与白色数量相等,求有多少非空区间 \([L,R]\) ,使得所有编号 \(\in[L,R]\) 的点形成的本质不同的合法简单路径数多于所有编号 \(\notin[L,R]\) 的点形成的本质不同的合法路径树。

题解

考虑所有以 \(x\) 为一个端点的合法简单路径数量为 \(F_x\) 。

设两端点编号分别位于 \([L,R]\) 之内和之外的路径树为 \(M\)

那么 \([L,R]\) 合法当且仅当 \(\sum\limits_{x\in[L,R]} F_x-M>\sum\limits_{x\notin[L,R]} F_x-M\)

即 \(\sum\limits_{x\in[L,R]} F_x>\sum\limits_{x\notin[L,R]} F_x\) 。

显然可以轻松的点分治求出 \(F_x\) ,然后随着 \(R\) 的增大, 极大的合法的 \(L\) 显然单调不减,所以类似滑动窗口一样的求就可以了。

#include<bits/stdc++.h>
#define debug(x) cerr<<#x<<" = "<<x
#define sp <<" "
#define el <<endl
#define fgx cerr<<"-----------------------------------"<<endl
#define LL long long
#define M 100010
using namespace std;
namespace IO{
const int BS=(1<<23)+5; int Top=0;
char Buffer[BS],OT[BS],*OS=OT,*HD,*TL,SS[20]; const char *fin=OT+BS-1;
char Getchar(){if(HD==TL){TL=(HD=Buffer)+fread(Buffer,1,BS,stdin);} return (HD==TL)?EOF:*HD++;}
void flush(){fwrite(OT,1,OS-OT,stdout),OS=OT;}
void Putchar(char c){*OS++ =c;if(OS==fin)flush();}
void write(int x){
if(!x){Putchar('0');return;} if(x<0) x=-x,Putchar('-');
while(x) SS[++Top]=x%10,x/=10;
while(Top) Putchar(SS[Top]+'0'),--Top;
}
int read(){
int nm=0,fh=1; char cw=Getchar();
for(;!isdigit(cw);cw=Getchar()) if(cw=='-') fh=-fh;
for(;isdigit(cw);cw=Getchar()) nm=nm*10+(cw-'0');
return nm*fh;
}
} using namespace IO;
int G[M<<1],mxs[M],n,m,fs[M],nt[M<<1],to[M<<1],tmp,F[M],V[M],sz[M]; bool vis[M]; LL ans=0;
inline void link(int x,int y){nt[tmp]=fs[x],fs[x]=tmp,to[tmp++]=y;}
#define rep for(int i=fs[x];i!=-1;i=nt[i]) if(to[i]!=last&&!vis[to[i]])
void fdrt(int x,int last,int all,int &RT){
mxs[x]=0,sz[x]=1; rep fdrt(to[i],x,all,RT),sz[x]+=sz[to[i]],mxs[x]=max(mxs[x],sz[to[i]]);
if((mxs[x]=max(mxs[x],all-sz[x]))<mxs[RT]) RT=x;
}
int init(int x,int last,int val){int res=abs(val+=V[x]);G[val+M]++,sz[x]=1;rep res=max(res,init(to[i],x,val)); return res;}
void getans(int x,int last,int val,int fh){sz[x]=1,val+=V[x],F[x]+=fh*G[M-val]; rep getans(to[i],x,val,fh),sz[x]+=sz[to[i]];}
inline void calc(int x,int last,int fh){
int len=init(x,last,last?V[last]:0)+1; getans(x,last,last?0:-V[x],fh);
for(int i=-len;i<=len;i++) G[i+M]=0;
}
void solve(int x,int all){
if(all==1){vis[x]=true;return;}int RT=0,last=0;fdrt(x,0,all,RT),x=RT;
vis[x]=true,calc(x,0,1); rep calc(to[i],x,-1); rep solve(to[i],sz[to[i]]);
}
int main(){
n=read(),memset(fs,-1,sizeof(fs)),mxs[0]=n;
for(int i=1;i<=n;i++) V[i]=(read()<<1)-1;
for(int i=1,x,y;i<n;i++) x=read(),y=read(),link(x,y),link(y,x);
solve(1,n); LL sum=0; for(int i=1;i<=n;i++) sum+=F[i]; sum>>=1;
for(int l=1,r=1,now=F[1];r<=n;r++,now+=F[r]){while(now>sum) now-=F[l++]; ans+=l-1;}
printf("%lld\n",ans); return 0;
}

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

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

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

  2. loj6119 「2017 山东二轮集训 Day7」国王

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. redis 系列文章推荐

    推荐博客: Redis在linux上的安装: http://www.open-open.com/lib/view/open1426468117367.html Redis的三种启动方式: http:/ ...

  2. linux:查看磁盘硬件信息hdparm,smartctl

    smartctl 命令 这个一个用于控制和监控支持smart技术的硬盘的命令.通常配合 -a 选项我们可以查看到比较详尽的硬盘信息(比如序列号.硬盘容量.已运行时间.硬盘健康状况等).用法如下: sm ...

  3. gh-ost原理

    gh-ost原理 一.三种模式架构图 1.连上从库,在主库上修改 这是gh-ost默认的工作模式,它会查看从库情况,找到集群的主库并且连接上去,对主库侵入最少,大体步骤是: 在主库上创建_xxx_gh ...

  4. 【Flask】Flask Session操作

    ### session:1. session的基本概念:session和cookie的作用有点类似,都是为了存储用户相关的信息.不同的是,cookie是存储在本地浏览器,session是一个思路.一个 ...

  5. 20145240 GDB调试汇编堆栈过程分析

    20145240 GDB调试汇编堆栈过程分析 测试代码 #include<stdio.h> short addend1 = 1; static int addend2 = 2; const ...

  6. Google maps api demo 2

    demo /** * @fileoverview Sample showing capturing a KML file click * and displaying the contents in ...

  7. Makefile文件应用——simple项目

    学习资料 本文主要参考资料:驾驭Makefile(李云).pdf 原理 (1)最基本的语法 targets: prerequisites command targets是目标,prerequisite ...

  8. C++ dll的隐式与显式调用

    应用程序使用DLL可以采用两种方式:一种是隐式链接,另一种是显式链接.在使用DLL之前首先要知道DLL中函数的结构信息.Visual C++6.0(或者更先进的版本)在VC\bin目录下提供了一个名为 ...

  9. scala学习手记29 - 偏应用函数

    调用函数可以说成是将函数应用于实参.如果传入所有的预期的参数,就完全应用了这个函数.如果只传入几个参数,就会得到一个偏应用函数. 偏应用函数是一个特殊的概念,在scala中它是使用val定义的,但是在 ...

  10. Ubuntu16.04 Kdevelop汉化及配置

    关闭Kdevelop sudo apt-get install kdevelop-l10n 再打开. 字体选择 Sans Serif :style:Normal:这样更舒服且不影响中文的排版,如何改成 ...