zoukankan      html  css  js  c++  java
  • [atAGC053F]ESPers

    记$Y$为在最后一次两者票数相同前投票的ESPer数量除以$K$,不难得到答案即$1-\frac{E(Y)}{2}$,问题也即求$E(Y)$

    为了方便叙述,称$S$为一种方案$,P_{S}$和$Y_{S}$分别为$S$的发生概率和$Y$,显然$E(Y)=\sum_{S}P_{S}Y_{S}$

    对于一个$S$,再构造序列$\{a_{i}\}$,规则如下:

    1.若第$i$次投票投给票数(严格)较多的一方或投票者是ESPer,则选择$a_{i}=1$

    2.若第$i$次投票投给票数(严格)较少的一方,则选择$a_{i}=-1$

    3.若不为上述情况(票数相同且投票者不是ESPer),则等概率选择$a_{i}=\pm 1$

    记$Q_{S,a}$为$S$得到$\{a_{i}\}$的概率,显然$\forall S,\sum_{a}Q_{S,a}=1$,代入即
    $$
    E(Y)=\sum_{S}Y_{S}P_{S}\sum_{a}Q_{S,a}=\sum_{a}\sum_{S}Y_{S}P_{S}Q_{S,a}
    $$
    换言之,考虑确定$\{a_{i}\}$后如何求出后者——

    将$\{a_{i}\}$表示成形如$S_{0},-1,S_{1},-1,...,S_{x},1,S_{x+1},1,...,S_{x+y}$的形式(其中$S_{i}$总和为0且任意前缀和非负、允许为空),注意到每次只能不断取最长的$S_{i}$,即形式是唯一的

    进一步的,注意到以下性质:

    1.ESPer恰可以出现在所有为1的位置,而每一个$S_{i}$中恰有一半是1

    2.其余人投票时若票数不同,会对$P_{S}$有$\frac{1}{2}$的贡献,否则会对$Q_{S,a}$有$\frac{1}{2}$的贡献,总贡献即$\frac{1}{2^{2n+1-K}}$

    3.最后一次出现两者票数相同发生在$E_{x}$($x$是偶数)或$E_{x-1}$($x$是奇数)的末尾

    综上,不难得到后者即
    $$
    \frac{\frac{2n+1-x+y}{2}\choose {K}}{(2n+1-x+y){2n+1\choose K}2^{2n+1-K}}\times \begin{cases}\sum_{i=0}^{x}|S_{i}|&x\equiv 0(mod\ 2)\\\sum_{i=0}^{x-1}|S_{i}|&x\equiv 1(mod\ 2)\end{cases}
    $$
    同时,$S_{i}$之间其实是等价的(可以任意排列),因此对于所有$S_{i}$上式期望是
    $$
    \frac{(2n+1-x-y){\frac{2n+1-x+y}{2}\choose {K}}}{(2n+1-x+y){2n+1\choose K}2^{2n+1-K}}\times\begin{cases}\frac{x+1}{x+y+1}&x\equiv 0(mod\ 2)\\\frac{x}{x+y+1}&x\equiv 1(mod\ 2)\end{cases}
    $$
    接下来,考虑$S_{i}$的方案数,在相邻两个$S_{i}$之间补上一个1,方案即对应于从$(0,0)$到$(2n+1,x+y)$的路径(形式参考卡特兰数),同时在路径中不断选最后一次与$y=0,1,...,x+y$有交的位置也可以对应于$S_{i}$

    参考卡特兰数的推导,可得$S_{i}$的方案数即${2n+1\choose \frac{2n+1-x-y}{2}}-{2n+1\choose \frac{2n-1-x-y}{2}}$

    综上,确定$x,y$​即可统计贡献,进而最终答案即
    $$
    \frac{1}{{2n+1\choose K}2^{2n+1-K}}\sum_{x\equiv 0(mod\ 2),y\equiv 1(mod\ 2)}\frac{(x+1)(n-k){\frac{2n+1-x+y}{2}\choose {K}}}{(k+1)(2n+1-x+y)}\left({2n+1\choose n-k}-{2n+1\choose n-k-1}\right)
    $$

    $$
    \frac{1}{{2n+1\choose K}2^{2n+1-K}}\sum_{x\equiv 1(mod\ 2),y\equiv 0(mod\ 2)}\frac{x(n-k){\frac{2n+1-x+y}{2}\choose {K}}}{(k+1)(2n+1-x+y)}\left({2n+1\choose n-k}-{2n+1\choose n-k-1}\right)
    $$

    (其中$k=\frac{x+y-1}{2}$,显然是整数)

    暴力计算复杂度为$o(n^{2})$,注意到两者是类似地,不妨仅优化前者

    具体的,改为枚举$k$和$x$并将$y=2k+1-x$​代入,即
    $$
    \frac{1}{{2n+1\choose K}2^{2n+1-K}}\sum_{k=0}^{n}\frac{(n-k)\left({2n+1\choose n-k}-{2n+1\choose n-k-1}\right)}{k+1}\sum_{x\le 2k+1,x\equiv 0(mod\ 2)}\frac{(x+1){n+k-x+1\choose {K}}}{2(n+k-x+1)}
    $$
    将${n+k-x+1\choose K}$变形为$\frac{n+k-x+1}{K}{n+k-x\choose K-1}$,进而关于$x$的枚举即
    $$
    \frac{1}{2K}\sum_{x\le 2k+1,x\equiv 0(mod\ 2)}(x+1){n+k-x\choose {K-1}}
    $$
    观察后者,不难发现维护${n\choose K-1}$中$n$(奇数项/偶数项)(乘$n$/不乘$n$)的前缀和即可$o(1)$求出

    时间复杂度为$o(n)$,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 4000005
     4 #define mod 1000000007
     5 #define ll long long
     6 int n,m,K,ans,fac[N],inv[N],Inv[N],sum[N],Sum[N];
     7 int C(int n,int m){
     8     if ((m<0)||(n<m))return 0;
     9     return (ll)fac[n]*Inv[m]%mod*Inv[n-m]%mod;
    10 }
    11 int get_sum(int l,int r){
    12     if (l<2)return sum[r];
    13     return (sum[r]-sum[l-2]+mod)%mod;
    14 }
    15 int get_Sum(int l,int r){
    16     if (l<2)return Sum[r];
    17     return (Sum[r]-Sum[l-2]+mod)%mod;
    18 }
    19 int main(){
    20     fac[0]=inv[0]=inv[1]=Inv[0]=1;
    21     for(int i=2;i<N;i++)inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
    22     for(int i=1;i<N;i++){
    23         fac[i]=(ll)fac[i-1]*i%mod;
    24         Inv[i]=(ll)Inv[i-1]*inv[i]%mod;
    25     }
    26     scanf("%d%d",&n,&K),m=(n<<1)+1;
    27     for(int i=0;i<N;i++){
    28         sum[i]=C(i,K-1),Sum[i]=(ll)i*sum[i]%mod;
    29         if (i>1){
    30             sum[i]=(sum[i]+sum[i-2])%mod;
    31             Sum[i]=(Sum[i]+Sum[i-2])%mod;
    32         }
    33     }
    34     for(int k=0;k<=n;k++){
    35         int s=0;
    36         s=(s+(ll)(n+k+1)*get_sum(n-k,n+k)-get_Sum(n-k,n+k)+mod)%mod;
    37         s=(s+(ll)(n+k)*get_sum(n-k-1,n+k-1)-get_Sum(n-k-1,n+k-1)+mod)%mod;
    38         s=(ll)s*inv[K]%mod*(mod+1>>1)%mod;
    39         ans=(ans+(ll)s*(n-k)%mod*(C(m,n-k)-C(m,n-k-1)+mod)%mod*inv[k+1])%mod;
    40     }
    41     ans=(ll)ans*Inv[m]%mod*fac[K]%mod*fac[m-K]%mod;
    42     for(int i=0;i<m-K;i++)ans=(ll)(mod+1>>1)*ans%mod;
    43     ans=(mod+1-(ll)(mod+1>>1)*ans%mod)%mod;
    44     printf("%d\n",ans);
    45     return 0; 
    46 } 
    View Code
  • 相关阅读:
    图灵机器人聊天api
    数据结构(七)之树
    Android批量图片载入经典系列——Volley框架实现多布局的新闻列表
    OCP试题解析之053-17 CONFIGURE CONTROLFILE AUTOBACKUP ON
    深入浅出理解排序算法之-堆排序
    【转】深入理解Android的startservice和bindservice--不错
    【转】Service Intent must be explicit的解决方法
    【转】Win7+Ubuntu12.04.1硬盘安装错误及解决方案----不错
    【转】Win7系统下安装Ubuntu12.04(EasyBCD硬盘安装)--不错
    【转】Ubuntu重装,直接进win7,不进linux的解决方案(添加Ubuntu启动菜单)
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15747938.html
Copyright © 2011-2022 走看看