zoukankan      html  css  js  c++  java
  • [bzoj3209][花神的数论题] (数位dp+费马小定理)

    Description

    背景
    众所周知,花神多年来凭借无边的神力狂虐各大 OJ、OI、CF、TC …… 当然也包括 CH 啦。
    描述
    话说花神这天又来讲课了。课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了。
    花神的题目是这样的
    设 sum(i) 表示 i 的二进制表示中 1 的个数。给出一个正整数 N ,花神要问你
    派(Sum(i)),也就是 sum(1)—sum(N) 的乘积。

    Input

    一个正整数 N。

    Output

    一个数,答案模 10000007 的值。

    Sample Input

    样例输入一

    3


    Sample Output

    样例输出一

    2

    HINT



    对于样例一,1*1*2=2;


    数据范围与约定


    对于 100% 的数据,N≤10^15

    Solution

    简单的数位dp,是论文的简化

    一样,预处理出f[i][j]代表i长度的二进制数下有j个1的数的数量

    求解具体数据先枚举1的数量,转移一下就行,之后用快速幂连乘

    难点:费马小定理的应用,对于极大的f[i][j],由于它是指数,无法直接和md取模,

    根据 a^phi(p)≡1(mod p),得出把f[i][j]和phi(10000007)=9988440取模就行了

    #include<iostream>
    #define ur 9988440
    #define md 10000007
    #define LL long long
    LL n,ans=1LL,f[53][53],tim[53];
    void init() {
        f[0][0]=1LL;
        for(int i=1; i<=50; i++) {
            f[i][0]=f[i-1][0];
            for(int j=1; j<=i; j++)
                f[i][j]=(f[i-1][j-1]+f[i-1][j])%ur; } }
    LL Q_pow(LL x,LL p) {
        LL res=1LL;
        for(; p; p>>=1LL) {
            if(p&1LL)
                res=(res*x)%md;
            x=(x*x)%md; }
        return res; }
    void calc() {
        int cnt=0;
        for(int i=50; ~i; i--) {
            if(n&(1LL<<i)) {
                for(int j=cnt; j<=50; j++)
                    tim[j]=(tim[j]+f[i][j-cnt])%ur;
                cnt++; } } }
    int main() {
        init();
        std::ios::sync_with_stdio(false);
        std::cin>>n; n++; calc();
        for(int i=1; i<=50; i++)
            ans=(ans*Q_pow(i,tim[i]))%md;
        std::cout<<ans<<std::endl;
        return 0; }
  • 相关阅读:
    LeetCode Single Number
    Leetcode Populating Next Right Pointers in Each Node
    LeetCode Permutations
    Leetcode Sum Root to Leaf Numbers
    LeetCode Candy
    LeetCode Sort List
    LeetCode Remove Duplicates from Sorted List II
    LeetCode Remove Duplicates from Sorted List
    spring MVC HandlerInterceptorAdapter
    yum
  • 原文地址:https://www.cnblogs.com/keshuqi/p/6282412.html
Copyright © 2011-2022 走看看