• 洛谷 P4317


    题目链接: P4317 花神的数论题

    题目大意

    详见题目

    solution

    (f_{i, j, k}) 表示长度为 (i) 最高位为 (j) 的且 (1) 的个数为 (k) 的数的个数

    1. (j=1, f_{i, j, k} = sumlimits_{p = 0}^{p leqslant 1}sumlimits_{k = 0}^{k leqslant i} f_{i - 1, p, k - 1})
    2. (j=0, f_{i, j, k} = sumlimits_{p = 0}^{p leqslant 1}sumlimits_{k = 0}^{k leqslant i} f_{i - 1, p, k})

    对于(ans_{1, r}) 我们可以采用以下策略 :

    (len)(r) 的位数, (a_{len})(r) 的每一位

    1. 对于首位为 (1) 且前面有 (cnt1)(1)(f) , (res = res * j^{f_{i, 0, j}}, i in [1, len), j in [1, len / 2 - cnt1])
    2. 对于首位为 (0)(f) , (res = res * j^{f_{i, 1, j}}, i in [1, len), j in [1, i / 2])

    那么答案就是 (ans_{1, r})

    Code:

    /**
    *    Author: Aliemo
    *    Data: 
    *    Problem: 
    *    Time: O()
    */
    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    
    #define int long long
    #define rr register
    
    #define inf 1e9
    #define MAXN 100010
    
    using namespace std;
    
    const int mod = 10000007;
    
    inline int read() {
    	int s = 0, f = 0;
    	char ch = getchar();
    	while (!isdigit(ch)) f |= ch == '-', ch = getchar();
    	while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
    	return f ? -s : s;
    }
    
    void print(int x) {
    	if (x < 0) putchar('-'), x = -x;
    	if (x > 9) print(x / 10);
    	putchar(x % 10 + 48);
    }
    
    int l, r, len;
    
    int f[80][2][80], a[50];
    
    inline int f_pow(int x, int y) {
    	int ans = 1;
    	while (y)  {
    		if (y & 1) ans = ans * x % mod;
    		x = x * x % mod;
    		y >>= 1;
    	}
    	return ans % mod;
    }
    
    inline void init() {
    	f[1][1][1] = 1, f[1][0][0] = 1;
    	for (rr int i = 2; i < 64; i++) 
    		for (rr int j  = 0; j <= 1; j++) 
    			for (rr int k = 0; k <= i; k++)
    				for (rr int p = 0; p <= 1; p++) 
    					if (!j) f[i][j][k] += f[i - 1][p][k];
    					else if (k) f[i][j][k] += f[i - 1][p][k - 1];
    }
    
    inline int solve(int x) {
    	memset(a, 0, sizeof a);
    	len = 0;
    	int ans = 0, cnt1 = 1;
    	while (x) {
    		a[++len] = x % 2;
    		ans += a[len];
    		x /= 2;
    	}
    	for (rr int i = len - 1; i >= 1; i--) {
    		int x = a[i];
    		if (x) {
    			for (rr int j = 0; j <= len - cnt1; j++)
    				if (f[i][0][j] != 0)
    					ans = (f_pow(j + cnt1, f[i][0][j]) * ans) % mod;
    		}
    		cnt1 += x;
    	}
    	for (rr int i = 1; i < len; i++)
    		for (rr int j = 1; j <= i; j++)
    			if (f[i][1][j] != 0) 
    				ans = (f_pow(j,f[i][1][j]) * ans) % mod;
    	return ans % mod;
    }
    
    signed main() {
    	init();
    	r = read();
    	cout << solve(r);
    }
    
  • 相关阅读:
    清空数据库所有表数据
    sqlserver编号
    Inherits、CodeFile、CodeBehind的区别
    初识NuGet
    ASP.Net各个命名空间及作用
    SQL SERVER数据库性能优化之SQL语句篇
    Exercise 20: Functions And Files
    Exercise 19: Functions And Variables
    Exercise 18: Names, Variables, Code, Functions
    Exercise 17: More Files
  • 原文地址:https://www.cnblogs.com/lieberdq/p/13992455.html
Copyright © 2020-2023  润新知