zoukankan      html  css  js  c++  java
  • [雅礼NOIP集训 2017] number 解题报告 (组合数+二分)

    题解:

    令$S(i)={i+1,i+2,...,i<<1}$,f(i,k)表示S(i)中在二进制下恰好有k个1的数的个数

    那么我们有$f(i,k)=sum_{x=1}^{min(k,p)}dbinom{a_x+1}{k-x+1}-dbinom{a_x}{k-x+1}$

    $a_x$表示i在二进制下第x的1所在的2的幂次,p是i在二进制下1的个数

    为什么呢?我们设g(i,k)表示在小于等于i的数中在二进制下1的个数等于k的数的个数,那么我们有f(i,k)=g(i<<1,k)-g(i,k)

    考虑怎么算g(i,k)。对于i的每一位1,我们强制把这一位变成0,假设这个1是第x高的1,在二进制下的次幂为$a_x$,那么我们保持前x-1个1不变,把剩下的k-x+1(+1是因为第x位变成了0空出了一个1)个1分配到从小到大$a_x$个位置里。由于第x位被强制变成了0,新分配的数一定满足1的个数为k且小于i;对于每一位1我们这样处理,可以保证方案数不重不漏

    如果本身i在二进制下就有k个1,那么i<<1在二进制下肯定也有k个1,这样方案数就抵消了,因此在上面的算式中没有考虑这样的情况

    下面来看两个结论:

    结论1:$f(i,k)<=f(i+1,k)$

    证明:

    显然i+1的S集合与i的S集合相比多了2*i+1,2*i+2,少了i+1,我们发现如果i+1是算入了贡献的,那么2*i+2显然也被算入了贡献,这样就抵消了,得证

    结论2:k>1时,$f(i,k)<f(i<<1,k)$

    这个,咱们感性理解一下吧,应该也不难证

    结论3:m=0时,n的个数为(1<<k-1)-1;k=1时,n一定可以取1,并且有正无穷个答案,其他情况答案都不是正无穷

    证明:

    m=0时,说明S集合中不存在一个数在二进制下1的个数为k,那么n的取值一定是小于等于(1<<k-1)-1的,不理解的话请注意S集合的定义

    k=1时,由于保证有解,m一定为1。正无穷个答案很好理解吧。至于其他情况答案有穷性,我也不会证

    由结论1得知,符合条件的n是连在一起的

    由结论2得知,当k>1时,所有的n都在2e18以内

  • 相关阅读:
    Sunday算法
    砝码称重 洛谷 1441
    树秀于林风必摧之——线段树
    常用stl(c++)
    Vue 根组件,局部,全局组件 | 组件间通信,案例组件化
    Win下JDK的安装和简单使用教程
    ubuntu服务器远程连接xshell,putty,xftp的简单使用教程
    ubuntu下安装pdo和pdo_mysql扩展
    服务器和域名的简单个人认知
    对大一一年的总结和对大二的规划
  • 原文地址:https://www.cnblogs.com/xxzh/p/9704705.html
Copyright © 2011-2022 走看看