Given a directed graph with nn nodes, labeled 0,1, \cdots, n-10,1,⋯,n−1.
For each <i, j><i,j> satisfies 0 \le i < j < n0≤i<j<n, there exists an edge from the i-th node to the j-th node, the capacity of which is ii xor jj.
Find the maximum flow network from the 0-th node to the (n-1)-th node, modulo 10000000071000000007.
Input Format
Multiple test cases (no more than 1000010000).
In each test case, one integer in a line denotes n(2 \le n \le 10^{18})n(2≤n≤1018).
Output Format
Output the maximum flow modulo 10000000071000000007 for each test case.
样例输入
2
样例输出
1
题目来源
题解:
打印出来相邻两个数的差是有规律的, 差值的规律如下:
2^0+1 第一次出现的位置为2^1, 第二次出现的位置为2^1+2^0, 接下来出现的位置依次为:2^1+2^0+k*2^1;
2^2+1 第一次出现的位置为2^2, 第二次出现的位置为2^2+2^1, 接下来出现的位置依次为:2^2+2^1+k*2^2;
2^4+1 第一次出现的位置为2^3, 第二次出现的位置为2^3+2^2, 接下来出现的位置依次为:2^3+2^2+k*2^3;
2^6+1 第一次出现的位置为2^4, 第二次出现的位置为2^4+2^3, 接下来出现的位置依次为:2^4+2^3+k*2^4;
依次类推.....
AC代码:
#include <iostream>
using namespace std;
typedef long long int ll;
ll a[200];
const ll mod=1000000007;
int main(){
ll n;
a[0]=1;
for(ll i=1; i<=62*2; i++) a[i]=(a[i-1]*2)%mod;
while(cin>>n){
ll ans=1, sum=1;
if(n==1){cout<<"0"<<endl;continue;}
for(ll i=1; i<=62; i++){
sum=sum*2;
if(sum>=n)break;
ll t=a[(i-1)*2]+1;
ans=(ans+t)%mod;
if(sum+sum/2<n)ans=(ans+t)%mod;
else continue;
if(sum+sum/2<n)ans=(ans+t%mod*(((n-1-(sum+sum/2))/sum)%mod))%mod;
}
cout<<ans<<endl;
}
return 0;
}