ARC 066D Xor Sum AtCoder - 2272 (打表找规律)
Problem Statement
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 xorb=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.
Constraints
- 1≦N≦10^{18}
Input
The input is given from Standard Input in the following format:
N
Output
Print the number of the possible pairs of integers u and v, modulo 10^9+7.
Sample Input 1
3
Sample Output 1
5
The five possible pairs of u and v are:
-
u=0,v=0 (Let a=0,b=0, then 0 xor 0=0, 0+0=0.)
-
u=0,v=2 (Let a=1,b=1, then 1 xor 1=0, 1+1=2.)
-
u=1,v=1 (Let a=1,b=0, then 1 xor 0=1, 1+0=1.)
-
u=2,v=2 (Let a=2,b=0, then 2 xor 0=2, 2+0=2.)
-
u=3,v=3 (Let a=3,b=0, then 3 xor 0=3, 3+0=3.)
Sample Input 2
1422
Sample Output 2
52277
Sample Input 3
1000000000000000000
Sample Output 3
787014179
思路:
打出前面一些项的答案:
1, 2, 4, 5, 8, 10, 13, 14, 18, 21, 26, 28, 33, 36, 40, 41, 46, 50, 57, 60, 68, 73, 80, 82, 89, 94, 102, 105, 112, 116, 121, 122, 128, 133, 142, 146, 157, 164, 174, 177, 188, 196, 209, 214, 226, 233, 242, 244, 253, 260, 272, 277, 290, 298, 309, 312, 322, 329,
可以发现这样的规律:
d
a(2k) = 2*a(k-1) + a(k);
a(2k+1) = 2*a(k) + a(k-1).
然后用数组记录前面一些项目,然后开一个map记录中间递归过程访问过的变量(即,记忆话搜索)
然后直接递归处理上面发现的递归式即可了。
这也是OEIS中的一个数列。
http://oeis.org/A007729
|
|||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||
|
细节见代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <iomanip> #define ALL(x) (x).begin(), (x).end() #define rt return #define dll(x) scanf("%I64d",&x) #define xll(x) printf("%I64d\n",x) #define sz(a) int(a.size()) #define all(a) a.begin(), a.end() #define rep(i,x,n) for(int i=x;i<n;i++) #define repd(i,x,n) for(int i=x;i<=n;i++) #define pii pair<int,int> #define pll pair<long long ,long long> #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define MS0(X) memset((X), 0, sizeof((X))) #define MSC0(X) memset((X), '\0', sizeof((X))) #define pb push_back #define mp make_pair #define fi first #define se second #define eps 1e-6 #define gg(x) getInt(&x) #define db(x) cout<<"== [ "<<x<<" ] =="<<endl; using namespace std; typedef long long ll; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;} inline void getInt(int* p); const int maxn=1000010; const int inf=0x3f3f3f3f; /*** TEMPLATE CODE * * STARTS HERE ***/ const ll mod=1e9+7ll; ll a[100]={1, 2, 4, 5, 8, 10, 13, 14, 18, 21, 26, 28, 33, 36, 40, 41, 46, 50, 57, 60, 68, 73, 80, 82, 89, 94, 102, 105, 112, 116, 121, 122, 128, 133, 142, 146, 157, 164, 174, 177, 188, 196, 209, 214, 226, 233, 242, 244, 253, 260, 272, 277, 290, 298, 309, 312, 322, 329, 340}; map<ll,ll> m; ll f(ll k) { // cout<<k<<endl; if(k<=50) { return a[k]; } if(m[k]) { return m[k]; } if(k&1) { return m[k]=(2ll*f(k/2ll)%mod+f(k/2ll-1ll)%mod)%mod; }else { return m[k]=(2ll*f(k/2ll-1ll)%mod+f(k/2ll)%mod)%mod; } } int main() { //freopen("D:\\common_text\\code_stream\\in.txt","r",stdin); //freopen("D:\\common_text\\code_stream\\out.txt","w",stdout); ll n; cin>>n; cout<<f(n)<<endl; return 0; } inline void getInt(int* p) { char ch; do { ch = getchar(); } while (ch == ' ' || ch == '\n'); if (ch == '-') { *p = -(getchar() - '0'); while ((ch = getchar()) >= '0' && ch <= '9') { *p = *p * 10 - ch + '0'; } } else { *p = ch - '0'; while ((ch = getchar()) >= '0' && ch <= '9') { *p = *p * 10 + ch - '0'; } } }