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. iOS 多线程安全 与可变数组

    完全来自于iOS 多线程安全与可变字典 的学习 基本相同,举一反三 直接上样例代码 是我参照网上,根据当前业务需求改的. 其实好多人在这里喜欢用类别处理.我个人觉得用类别 极其容易和普通方法混淆,所以 ...

  2. Bootstrap总结二

    参考我的博客:http://www.isedwardtang.com/2017/09/01/bootstrap-primer-2/

  3. addEventListener和attachEvent介绍, 原生js和jquery的兼容性写法

    也许很多同仁一听到事件监听,第一想到的就是原生js的 addEventListener()事件,的确如此,当然如果只是适用于现代浏览器(IE9.10.11 | ff, chorme, safari, ...

  4. 反射_获取字段的Description信息

    var memInfo = enumType.GetType().GetMember(enumType.ToString()); var attributes = memInfo[0].GetCust ...

  5. ubuntu16.04的anacoda内置的spyder不支持中文【学习笔记】

    执行下面的语句:将libfcitxplatforminputcontextplugin.so复制到anaconda2的安装目录下的platforminputcontexts目录重启生效 cp /usr ...

  6. redhat 6.8 配置yum源

    一般安装好redhat后,不能注册的话,不能使用系统自带的yum源.但是我们可以自己配置yum源来解决这一问题.下面介绍下redhat配置163yum源. 1. 检查是否安装yum包 rpm -qa ...

  7. EF Code-First 学习之旅 多对多的关系

    public class Student { public Student() { this.Courses = new HashSet<Course>(); } public int S ...

  8. Elasticsearch 配置优化

    cluster.routing.allocation.same_shard.host:true 这会防止同一个shard的主副本存在同一个物理机上(因为如果存在一个机器上,副本的高可用性就没有了). ...

  9. PHP学习之路(一)

    先前对PHP的学习研究,今总结写下心得!!

  10. 运行【guns】spring boot 的四种方式

    IDE 运行 运行带有main方法类 用mvn运行Spring-boot项目 在父项目中运行 mvn clean mvn install 在主项目中运行 mvn spring-boot:run 用JA ...