萌新刚学oi,求助/kk
查看原帖
萌新刚学oi,求助/kk
127873
1ink楼主2020/12/6 20:41

我写的数论dp,dfs形式,小调试一下感觉问题应该出在限制的锅?(3、7等二进制全为1的数跟题解对拍能过,其他过不了)

//#include <bits/stdc++.h>
#include <queue>
#include <iostream>
#include <iomanip>
#include <math.h>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <string>
#define F(i, a, b) for(register int i = a, i##end = b; i <= i##end; i++)
#define UF(i, a, b) for(register int i = a, i##end = b; i >= i##end; i--)
#define ll long long
using namespace std;
inline ll read() 
{
    ll x = 0;
    bool fu = 0;
    char ch = 0;
    while(ch > '9' || ch < '0') 
    {
        ch = getchar();
        if(ch == '-')
            fu = 1;
    }
    while(ch <= '9' && ch >= '0') 
        x = (x * 10 - 48 + ch), ch = getchar();
    return fu ? -x : x;
}
const ll mod = 10000007;
ll dp[70][70];
ll n;
int pos;
int limits[70];
ll dfs(int n, int m, int limit)
{
    if(n < m || m < 0)//不合法
    {
        return 0;
    }
    if(n == 0)//合法的基本单位
    {
        return 1;
    }
    if(dp[n][m])//记忆化搜索
    {
        return dp[n][m];
    }
    if(!limit)//不被限制
    {
        return dp[n][m] = dfs(n - 1, m, 0) + dfs(n - 1, m - 1, 0);//0或1都不被限制
    }
    if(limits[n])//被限制,但是此位有两种选择
        return dp[n][m] = dfs(n - 1, m, 0) + dfs(n - 1, m - 1, 1);//选0则下一位不被限制,选1则下一位仍被限制
    return dp[n][m] = dfs(n - 1, m, 1);//只能选0,下一位必被限制
}
ll qpow(ll a, ll b)
{
    ll ans = 1;
    while(b)
    {
        if(b & 1)
        {
            ans *= a;
            ans %= mod;
        }
        a *= a;
        a %= mod;
        b >>= 1;
    }
    return ans;
}
int main()
{
    ll ans = 1;
    n = read();
    while(n)
    {
        limits[++pos] = n & 1;
        n >>= 1;
    }
    F(i, 1, pos)
    {
        dfs(pos, i, 1);
    }
    F(i, 1, pos)
    {
        ans = ans * qpow(i, dp[pos][i]) % mod;
    }
    printf("%lld\n", ans);
    getchar();
    return 0;
}
2020/12/6 20:41
加载中...