• BZOJ4475 [Jsoi2015]子集选取


    Description

    有一些({1dots n})的子集(A_{i,j}, 1leq jleq ileq k)(frac{k(k+1)}2)个,满足(A_{i,j}subset A_{i+1,j}, A_{i,j}subset A_{i,j+1})。求这些集合有多少种方案。如果(A)(B)两种方案中存在(i,j)使得(A_{i,j} eq B_{i,j}),则它们是不同的。(n, kleq 10^9)

    Solution

    对于(n=1)求出方案数,之后将这个方案数取(n)次幂即可。因为不同的元素之间是互不影响的。

    (n=1)时,我实际上要从

    [egin{matrix} A_{1,1}\ A_{2,1}&A_{2,2}\ A_{3,1}&A_{3,2}&A_{3,3}\ vdots&vdots&vdots&ddots\ A_{k,1}&A_{k,2}&A_{k,3}&cdots&A_{k,k} end{matrix} ]

    这个三角中选出一些来包含(1)

    那么,我从这个矩阵左下角即(A_{k,1})的左下方开始,每次向右或上走一步,直到某个(A_{i,i})的左上角(或者(A_{k,k})的右下角);走出这个折线的右下的集合包含(1),其它不包含(1)。那么我一共会走((k-i+1)+(i-1)=k)步,每步可以向右/下走,所以共有(2^k)种方案。

    综上,答案即为(2^{nk})

    Code

    #include <cstdio>
    typedef long long LL;
    const int mod = 1000000007;
    int main() {
      int n, k;
      scanf("%d%d", &n, &k);
      int ans = 1, x = 2;
      for (n = (LL)n * k % (mod - 1); n; n >>= 1, x = (LL)x * x % mod)
        if (n & 1) ans = (LL)ans * x % mod;
      return printf("%d
    ", ans) & 0;
    }
    
  • 相关阅读:
    java Boolean和boolean的区别
    stack.isEmpty()和empty()
    mysql中文、英文别名排序问题,order by 关键字详解
    数组中array==null和array.length==0的区别
    7.9总结
    7.8总结
    6.25总结
    6.27总结
    6.29总结
    6.28总结
  • 原文地址:https://www.cnblogs.com/y-clever/p/8512586.html
Copyright © 2020-2023  润新知