ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P4317 花神的数论题

2019-09-14 10:57:44  阅读:284  来源: 互联网

标签:ch int res ll 花神 论题 P4317 include mo


传送门

考虑把 $sum$ 值相同的一起用快速幂计算

枚举 $sum=i$ ,然后可以用数位 $dp$ 求有多少小于 $n$ 的二进制下恰好有 $i$ 个 $1$ 的数的个数

注意不要把个数取模,因为个数是幂次

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline ll read()
{
    ll x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=233,mo=10000007;
inline ll fk(ll x) { return x>=mo ? x-mo : x; }
ll n,C[N][N],ans=1;
ll b[N],res;
void dfs(int p,int t)
{
    if(!t) { res++; return; }
    if(!p) return;
    if(!b[p]) dfs(p-1,t);
    else res+=C[p-1][t],dfs(p-1,t-1);
}
ll ksm(ll x,ll y)
{
    ll res=1;
    while(y)
    {
        if(y&1) res=res*x%mo;
        x=x*x%mo; y>>=1;
    }
    return res;
}
int main()
{
    n=read();
    for(int i=0;i<64;i++)
    {
        C[i][0]=1;
        for(int j=1;j<=i;j++) C[i][j]=C[i-1][j-1]+C[i-1][j];
    }
    int len=0; ll t=n; while(t) b[++len]=t&1,t>>=1;
    for(int i=1;i<=len;i++)
    {
        res=0; dfs(len,i);
        ans=ans*ksm(i,res)%mo;
    }
    printf("%lld\n",ans);
    return 0;
}

 

标签:ch,int,res,ll,花神,论题,P4317,include,mo
来源: https://www.cnblogs.com/LLTYYC/p/11518548.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有