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

    披着数论题外衣的数位dp。

    相当于数一数$[1,n]$范围内$1$的个数是$1,2,3,4,...log(n)$的数各有多少个,直接在二进制下数位dp。

    然而我比较sb地把(1e7 + 7)当成了质数,其实数出来的数是要模$phi(p)$的,然而数出来的数绝对不会超过$n$。

    时间复杂度$O(log^{4}n + sqrt{P})$。

    Code:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    
    const int N = 65;
    const ll P = 1e7 + 7;
    
    int len, bit[N];
    ll f[N][N], phiP;
    
    inline ll pow(ll x, ll y) {
        ll res = 1LL;
        for(; y > 0; y >>= 1) {
            if(y & 1) res = res * x % P;
            x = x * x % P;
        } 
        return res;
    }
    
    ll dfs(int pos, int cnt, bool lead, bool lim, int cur) {
        if(pos == 0) return (cnt == cur);
        if(!lead && !lim && f[pos][cnt] != -1) return f[pos][cnt];
        
        ll res = 0LL; int num = lim ? bit[pos] : 1;
        for(int i = 0; i <= num; i++)
            res = (res + dfs(pos - 1, cnt + (i == 1), lead && (i == 0), lim && (i == bit[pos]), cur)) % phiP;
        
        if(!lim && !lead) f[pos][cnt] = res;
        return res;
    }
    
    inline ll solve(int k) {
        memset(f, -1, sizeof(f));
        ll res = dfs(len, 0, 1, 1, k);
        return res;
    }
    
    inline ll getPhi(ll now) {
        ll res = now, tmp = now; 
        for(int i = 2; i * i <= now; i++) 
            if(tmp % i == 0) {
                res = res / i * (i - 1);
                for(; tmp % i == 0; tmp /= i);
            }
        if(tmp != 1) res = res / tmp * (tmp - 1);
        return res;
    }
    
    int main() {
        phiP = getPhi(P);
    //    printf("%lld
    ", phiP);
        
        ll n; scanf("%lld", &n);
        
        len = 0;
        for(ll tmp = n; tmp > 0; tmp >>= 1)
            bit[++len] = (tmp & 1);
        
        ll ans = 1LL;
        for(int i = 1; i <= len; i++)
            ans = ans * pow(i, solve(i) % phiP) % P;
        
        printf("%lld
    ", ans);
        return 0;
    }    
    View Code
  • 相关阅读:
    oracle spatial 类型
    感悟
    给年轻工程师的十大忠告
    美剧
    幸福人生讲座(一):不学礼,无以立
    人成长中须知道的20个故事
    孔子
    毕业五年决定你的一生
    sysindexes表中求SELECT COUNT(*)
    我们应该懂得
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9649827.html
Copyright © 2011-2022 走看看