标签:HERE positive printf exist 偶数 lin 递归 can let
You are given a positive integer \(N\). Find the number of the pairs of integers \(u\) and \(v(0≤u,v≤N)\)such that there exist two non-negative integers \(a\) and \(b\) satisfying \(a xor b =u\) and \(a+b=v\). Here, \(xor\) denotes the bitwise exclusive OR. Since it can be extremely large, compute the answer modulo \(10^9+7\).
\(1≤N≤10^{18}\)
The input is given from Standard Input in the following format:
\(N\)
Print the number of the possible pairs of integers \(u\) and \(v\), modulo \(10^9+7\).
3
5
The five possible pairs of \(u\) and \(v\) are:
1422
52277
1000000000000000000
787014179
给出正整数N,求出整数对\(u\)和\(v (0≤u,v≤N)\)的数目,
使得存在两个非负整数\(a\)和\(b\)满足\(a xor b = u\) 和\(a + b= v\)。
这里,\(xor\)表示按位异或。对答案取模\(10^9 + 7\)
一上来直接懵逼,什么\(xor\),那就先打个表
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 30;
int n = 20, num[N];
int main() {
for(int i = 0; i <= n; i++) {
int s = 0;
for(int u = 0; u <= i; u++) {
memset(num, 0, sizeof(num));
for(int a = 0; a <= u; a++) {
int b = u - a;
if ((a xor b) <= i) num[a xor b] = 1;
}
for(int j = 0; j <= i; j++)
if (num[j]) s++;
}
printf("a[%d] = %d,", i, s);
}
return 0;
}
打表的结果如下
a[0] = 1,a[1] = 2,a[2] = 4,a[3] = 5,a[4] = 8,a[5] = 10,
a[6] = 13,a[7] = 14,a[8] = 18,a[9] = 21,a[10] = 26,
a[11] = 28,a[12] = 33,a[13] = 36,a[14] = 40,a[15] = 41,
a[16] = 46,a[17] = 50,a[18] = 57,a[19] = 60,a[20] = 68,
设结果为\(f_x\)
经过各种操作白嫖,得到如下递推式:
由于数据是1e18的,不记忆化会超时
记忆化开数组会爆掉,就用了map来做记忆化
#include <cstdio>
#include <map>
#define int long long
using namespace std;
const int M = 1e9+7;
map<int, int> a;
int n;
int dfs(int x) {
if (a[x]) return a[x];
if (x % 2) return a[x] = (2 * dfs(x / 2) + dfs(x / 2 - 1)) % M;
else return a[x] = (dfs(x / 2) + 2 * dfs(x / 2 - 1)) % M;
}
signed main() {
a[0] = 1; a[1] = 2;
scanf("%lld", &n);
printf("%lld", dfs(n));
return 0;
}
标签:HERE positive printf exist 偶数 lin 递归 can let
原文地址:https://www.cnblogs.com/Z8875/p/12864462.html