zoukankan      html  css  js  c++  java
  • 【CF643F】Bears and Juice(信息与可区分情况数)

    点此看题面

    • (n)头熊和若干桶果汁以及一桶酒。
    • 每天每只熊会选择若干桶饮料喝一杯,如果喝到了酒就会去睡觉再也不回来。
    • 总共只有(p)个睡觉的位置,如果睡觉的熊超过了(p)头或者所有熊都睡觉了就失败了。
    • (f_i)表示(i)天内在这些熊能找出酒的位置的前提下的最大桶数,求(oplus_{i=1}^q(i imes f_i)(mod 2^{32}))
    • (nle10^9,ple130,qle2 imes10^6)

    “信息”

    非常巧妙的一个转化!

    我们可以先通过一个例子来感受一下“信息”与可区分情况数之间的联系。

    例如排序,为什么一般的基于比较的排序复杂度最快只能达到(O(nlog_2n))

    考虑通过一次比较,我们获得的信息能够区分出两种不同的情况,因此(k)次比较总共就能区分出(2^k)种情况。

    而排序要求的是把序列从总共的(n!)种情况中区分出来,就需要满足(2^kge n!)

    因此(kge log_2(n!)≈nlog_2n)

    可区分情况数

    在这题中,由于有多少个桶,酒所在的位置就有多少种情况,因此问最多能有多少桶,其实就是问我们通过(i)天操作得到的信息最多能区分出多少种不同的情况。

    首先,由于不能所有熊都睡着,因此当(p>n-1)时多余的位置其实是没意义的,因此我们完全可以在一开始就令(p=min{p,n-1})

    然后,考虑有多少种可区分情况,先枚举有多少头熊睡觉了,再考虑睡觉的是哪些熊、分别在哪一天睡着,得到:

    [f_i=sum_{j=0}^{p}C_n^j imes i^j ]

    要注意,这道题之所以可以这样算,是因为不同的信息必然可以对应出一种不同的可区分情况,不能盲目把这个方法套用到所有题目上去。

    对于组合数的预处理

    上面这个式子显然可以(O(pq))计算,唯一的问题就在于如何在模(2^{32})意义下求组合数,这应该是这道题另一个比较妙的地方,尽管与前面那位相比逊色不少。

    发现(p)很小,我们直接列出所有的分子和分母,枚举每对分子和分母约分,根据组合数的定义最终必然能把所有分母约成(1),那么再直接把所有分子乘起来即可得出组合数了。

    代码:(O(pq+p^3logp))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define P 130
    #define LL long long
    using namespace std;
    int n,p,q,a[P+5],b[P+5];unsigned C[P+5];
    I int gcd(CI x,CI y) {return y?gcd(y,x%y):x;}
    int main()
    {
    	RI i,j,k,g;for(scanf("%d%d%d",&n,&p,&q),p=min(p,n-1),i=0;i<=p;++i)//求C(n,i)
    	{
    		for(j=1;j<=i;++j) a[j]=n-j+1,b[j]=j;//列出所有分子和分母
    		for(j=1;j<=i;++j) for(k=1;k<=i;++k) g=gcd(a[j],b[k]),a[j]/=g,b[k]/=g;//枚举每对分子和分母约分
    		for(C[i]=j=1;j<=i;++j) C[i]*=a[j];//将所有分子乘起来
    	}
    	unsigned w,t,s=0;for(i=1;i<=q;s^=i*t,++i) for(w=1,t=j=0;j<=p;w*=i,++j) t+=C[j]*w;//枚举每一天计算可区分情况数
    	return printf("%u
    ",s),0;
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    PAT甲题题解-1106. Lowest Price in Supply Chain (25)-(dfs计算树的最小层数)
    PAT甲题题解-1105. Spiral Matrix (25)-(模拟顺时针矩阵)
    PAT甲题题解-1102. Invert a Binary Tree (25)-(建树,水题)
    PAT甲题题解-1101. Quick Sort (25)-大水题
    PAT甲级题解-1100. Mars Numbers (20)-字符串处理
    XJOI网上同步训练DAY1 T2
    XJOI网上同步训练DAY1 T1
    BZOJ 1061 志愿者招募
    BZOJ 2432 兔农
    KMP算法总♂结
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/CF643F.html
Copyright © 2011-2022 走看看