zoukankan      html  css  js  c++  java
  • P4317 花神的数论题

    传送门

    考虑把 $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
    ",ans);
        return 0;
    }
  • 相关阅读:
    文件同步工具
    截图工具
    DBF文件工具
    Oracle旗下的开源虚拟机
    远程协助工具
    切换网络IP工具
    MySQL(C#的链接姿势)
    大写URL转小写
    一个textview实现文字在图片上面的效果
    通过代码设置textview颜色
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11518548.html
Copyright © 2011-2022 走看看