码迷,mamicode.com
首页 > 其他好文 > 详细

【题解】Luogu P4317 花神的数论题 组合数

时间:2019-10-10 15:48:21      阅读:77      评论:0      收藏:0      [点我收藏+]

标签:spl   bit   sum   pac   col   code   快速幂   ide   cli   

前言

今天实在是太冷了!!!

o(*////▽////*)q

导致我这个菜鸡硬生生把一道数位dp写成了组合数水过(还不是因为数位dp题解没看懂


 

显然题意都告诉你了,$sum(i)$表示二进制位下的几个一,可以想到组合意义,在一个$i$位的二进制数中填$j$个1的方案数

预处理个50*50的杨辉三角,完全不需要求线性逆元

最后快速幂累乘出答案即可

 

code

技术图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 namespace gengyf{
 4 #define ll long long
 5 #define int long long
 6 const int maxn=1e4+10;
 7 const int mod=1e7+7;
 8 inline int read(){
 9     int f=1,x=0;char s=getchar();
10     while(s<0||s>9){if(s==-)f=-1;s=getchar();}
11     while(s>=0&&s<=9){x=x*10+s-0;s=getchar();}
12     return f*x;
13 }
14 int n,C[55][55],d[maxn],num[maxn],ans=1;
15 void pre(){
16     for(int i=0;i<=50;i++)C[i][0]=1;
17     for(int i=1;i<=50;i++)
18         for(int j=1;j<=50;j++){
19             C[i][j]=C[i-1][j]+C[i-1][j-1];
20         }
21 }
22 int qpow(int a,int b){
23     int tmp=1;
24     while(b){
25         if(b&1)tmp=tmp*a%mod;
26         a=a*a%mod;b>>=1;
27     }
28     return tmp;
29 }
30 int main(){
31     n=read();
32     pre();
33     int len=0,cnt=0;
34     while(n){
35         d[++len]=n&1;
36         n>>=1;
37     }
38     for(int i=len;i;--i){
39         if(d[i]){
40             for(int j=1;j<i;++j)
41                 num[cnt+j]+=C[i-1][j];
42                 ++num[++cnt];
43         }
44     }
45     for(int i=1;i<=len;++i){
46         ans=ans*qpow(i,num[i])%mod;
47     }
48     printf("%lld",ans);
49     return 0;
50 }
51 }
52 signed main(){
53   gengyf::main();
54   return 0;
55 }
View Code

 


后续

在写这篇$boke$的时候,一只大佬飘过,顺便说他用的数位dp,又被了

 

【题解】Luogu P4317 花神的数论题 组合数

标签:spl   bit   sum   pac   col   code   快速幂   ide   cli   

原文地址:https://www.cnblogs.com/gengyf/p/11648163.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!