题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2839

设 \( f(i) \) 为至少 \( i \) 个选择,则 \( f(i) = C_{n}^{i} * (2^{2^{n-i}} - 1) \),因为其他可选可不选;

设 \( g(i) \) 为恰好 \( i \) 个选择,则 \( f(i) = \sum\limits_{j=i}^{n} g(j) * C_{j}^{i} \)

感觉形式不是一般那种,所以想换一下,设 \( f(i) \) 为至多 \( i \) 个不选,则 \( f(i) = C_{n}^{i} * (2^{2^{i}} - 1) \)

\( g(i) \) 为恰好 \( i \) 个不选,则 \( f(i) = \sum\limits_{j=0}^{i} g(j) * C_{i}^{j} \)

则 \( g(i) = \sum\limits_{j=0}^{i} (-1)^{i-j} * C_{i}^{j} * f(j) \)

然而这样求 \( g(n-k) = \sum\limits_{i=0}^{n-k} (-1)^{n-k-i} * C_{n-k}^{i} * f(i) \) 却不对...改成

\( g(n-k) = \sum\limits_{i=0}^{n-k} (-1)^{n-k-i} * C_{n-i}^{k} * f(i) \) 却对了...不明白啊...

后来知道上面那个形式也可以直接反演 \( g(i) = \sum\limits_{j=i}^{n} (-1)^{j-i} * C_{j}^{i} * f(j) \)

还是不明白那种做法,组合数为什么...

注意放在指数的数是对 mod-1 取模!

upt:如果 \( f(i) \) 是至多 \( i \) 个不选,那么 \( f(i) = \sum\limits_{j=0}^{i} C_{n-j}^{n-i} * g(j) \),而不是 \( C_{i}^{j} \)

因为“至多 \( i \) 个”,所以 \( i \) 是不确定的,而 \( n-i \) 确定必选,算方案的时候也是 \( f(i) = C_{n}^{i} * (2^{2^{i}}-1) \)

所以应该是在能确定的部分中进行选择,也就是 \( C_{n-j}^{n-i} \) !

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
int const xn=1e6+,mod=1e9+;
int n,k,jc[xn],jcn[xn],f[xn];
ll pw(ll a,int b,int md){ll ret=; for(;b;b>>=,a=a*a%md)if(b&)ret=ret*a%md; return ret;}
int upt(int x){while(x>=mod)x-=mod; while(x<)x+=mod; return x;}
void init()
{
jc[]=;
for(int i=;i<=n;i++)jc[i]=(ll)jc[i-]*i%mod;
jcn[n]=pw(jc[n],mod-,mod);
for(int i=n-;i>=;i--)jcn[i]=(ll)jcn[i+]*(i+)%mod;
}
int C(int n,int m){return (ll)jc[n]*jcn[m]%mod*jcn[n-m]%mod;}
int main()
{
n=rd(); k=rd(); init();
for(int i=;i<=n;i++)f[i]=(ll)C(n,i)*(pw(,pw(,i,mod-),mod)-)%mod;//
int ans=;
for(int i=;i<=n-k;i++)ans=upt(ans+(ll)C(n-i,k)*f[i]*(((n-k-i)&)?-:)%mod);//C(n-k,i)?
/* //也可
for(int i=0;i<=n;i++)f[i]=(ll)C(n,i)*(pw(2,pw(2,n-i,mod-1),mod)-1)%mod;//
int ans=0;
for(int i=k,t=1;i<=n;i++,t=-t)ans=upt(ans+(ll)C(i,k)*f[i]*t%mod);
*/
printf("%d\n",ans);
return ;
}

最新文章

  1. js获取当前页面信息
  2. 用Path来绘制一些图形
  3. 2016 - 1- 22 NSURLConnetction --- POST请求
  4. poj1009
  5. android requestDisallowInterceptTouchEvent用途
  6. hdu5351 MZL&#39;s Border(规律题,java)
  7. Java日期计算之Joda-Time
  8. weaver_oa
  9. iOS开发网络篇之文件下载、大文件下载、断点下载
  10. VB6之多维数组中元素在内存中的排列情况
  11. Codeforces Round #487 (Div. 2) C - A Mist of Florescence
  12. 国密SM3算法在linux和windows平台结果不一致问题
  13. BZOJ 4242 水壶(BFS建图+最小生成树+树上倍增)
  14. Dubbo简单环境搭建
  15. oracle数据类型及其隐式转换
  16. 扩展C#与元编程(一)
  17. Java 之常用API(二)
  18. 对一致性Hash算法及java实现(转)
  19. 执行composer install 报错的解决办法
  20. pahlcon:cookies设置

热门文章

  1. 20145240 《Java程序设计》第一次实验报告
  2. .NET自带泛型委托方法Func、Action和Predicate
  3. oracle 字典表查询
  4. JAVA获取webapp路径
  5. Email-Ext Plugin install ------ Jenkins Plugins
  6. ubuntu环境下安装Redis
  7. DB处理大量数据处理日志报错问题
  8. MySql基础学习-库表操作
  9. Mac开机启动
  10. MySQL 大数据量修改表结构问题