zoukankan      html  css  js  c++  java
  • BZOJ4475[Jsoi2015]子集选取——递推(结论题)

    题目描述

    输入

    输入包含一行两个整数N和K,1<=N,K<=10^9

    输出

    一行一个整数,表示不同方案数目模1,000,000,007的值。

    样例输入

    2 2

    样例输出

    16
     
    可以发现对于集合中每个元素的选取都是互不影响的,设$f(n,k)$为输入$n,k$时的答案,那么$f(n,k)=f(1,k)^n$。
    我们现在来推导$f(1,k)$的结果:可以发现$1$的位置一定是连续的,设$a_{i}$表示第$i$列最后选取到了$a_{i}$行,若从第$1$列到第$m$列均存在被选取。
    那么可以得到结论:$a_{i+1}le a_{i}(1le i <m)$。
    设$g[i][j]$表示只有前$i$列有$1$,其中第$i$列最后选取到了第$j$行的方案数,可以得到递推式:$g[i][j]=sumlimits_{p=j}^{k}g[i-1][p]$。
    通过观察可以得到:$g[i][j]=g[i-1][j]+g[i][j+1]$,这实际上就是一个顺时针旋转了$45^{circ}$的杨辉三角。
    那么加上都不选取的方案数为$1$,$f(1,k)=1+sum g[i][j]=2^k$,由此可得$f(n,k)=2^{nk}$。
    #include<set>
    #include<map>
    #include<queue>
    #include<cmath>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    using namespace std;
    int n,k;
    int mod=1000000007;
    ll quick(ll x,ll y)
    {
    	ll res=1;
    	while(y!=0)
    	{
    		if(y%2==1)
    		{
    			res=(res*x)%mod;
    		}
    		x=(x*x)%mod;
    		y/=2;
    	}
    	return res%mod;
    }
    int main()
    {
    	scanf("%d%lld",&n,&k);
    	ll sum=1ll*n*k;
    	printf("%lld",quick(2,sum));
    }
  • 相关阅读:
    JavaScript深复制
    Javascript Date Format
    SqlHelper include Transaction
    JQuery 对 Select option 的操作---转载
    转载:SQL索引一步到位
    转载 SQL Server 2008 R2 事务与隔离级别实例讲解
    使用Log Explorer查看和恢复数据
    SqlServer正在执行的sql语句
    SQL Server Reporting Services – Insufficient Rights Error
    asp.net 间传值的方法
  • 原文地址:https://www.cnblogs.com/Khada-Jhin/p/10460244.html
Copyright © 2011-2022 走看看