• 【LG4317】花神的数论题


    【LG4317】花神的数论题

    题面

    洛谷

    题解

    (f_{i,up,tmp,d})表示当前在第(i)位,是否卡上界,有(tmp)个一,目标是几个一的方案数

    最后将所有(d)固定,套数位(dp)的板子

    然后快速幂乘起来就好了

    代码

    #include <iostream> 
    #include <cstdio>
    #include <cstdlib>
    #include <cstring> 
    #include <cmath> 
    #include <algorithm>
    #include <vector> 
    using namespace std;
    #define int long long 
    const int Mod = 1e7 + 7; 
    int N, f[55][2][55][55];
    vector<int> digit;
    int fpow(int x, int y) {
    	int res = 1;
    	while (y) {
    		if (y & 1) res = 1ll * res * x % Mod; 
    		x = 1ll * x * x % Mod;
    		y >>= 1ll; 
    	}
    	return res; 
    } 
    int dfs(int o, bool up, int tmp, int d) { 
    	if (o == -1) return tmp == d; 
    	if (~f[o][up][tmp][d]) return f[o][up][tmp][d]; 
    	int lim = up ? digit[o] : 1, res = 0; 
    	for (int i = 0; i <= lim; i++) res = res + dfs(o - 1, up && i == lim, tmp + (i == 1), d); 
    	return f[o][up][tmp][d] = res; 
    }
    int ans[100]; 
    int solve(int n) { 
    	while (n) digit.push_back(n & 1ll), n >>= 1ll;
    	digit.push_back(0); 
    	for (int i = 1; i <= 50; i++) {
    		memset(f, -1, sizeof(f)); 
    		ans[i] = dfs(digit.size() - 1, 1, 0, i); 
    	} 
    	int res = 1;
    	for (int i = 1; i <= 50; i++) res = 1ll * res * fpow(i, ans[i]) % Mod;
    	return res; 
    } 
    signed main () {
    	cin >> N; 
    	printf("%lld
    ", solve(N)); 
    	return 0; 
    } 
    
  • 相关阅读:
    安卓天天练练(三)常用组件Toast
    安卓天天练练(二)相对布局和帧布局
    javascript表单操作
    JavaScript replace() 方法
    android基础(一)
    四大类NoSQL数据库
    php基础八(cookie)
    php基础(七)文件
    php基础(六)Include
    php基础(五)日期
  • 原文地址:https://www.cnblogs.com/heyujun/p/10225228.html
Copyright © 2020-2023  润新知