题目:https://nanti.jisuanke.com/t/17118
题意:
n个点,任意两点i,j(0≤i
i 值 和前一个值的差
2 1 1
3 3 2
4 5 2
5 10 5
6 12 2
7 17 5
8 19 2
9 36 17
10 38 2
11 43 5
12 45 2
13 62 17
14 64 2
15 69 5
16 71 2
17 136 65
18 138 2
19 143 5
20 145 2
21 162 17
22 164 2
23 169 5
24 171 2
25 236 65
26 238 2
27 243 5
28 245 2
29 262 17
30 264 2
可发现规律如下:
打印出来相邻两个数的差是有规律的, 差值的规律如下:
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;
依次类推…..
参考:http://www.voidcn.com/article/p-qbdagdra-bnw.html
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int mod=1e9+7;
const int N=1000+2;
LL p[N];
int main()
{
p[0]=1;
for(int i=1;i<=62*2;i++)
p[i]=p[i-1]*2%mod;
LL n;
while(cin>>n){
LL ans=1,sum=1;
for(int i=1;i<=62;i++){
sum<<=1;
if(sum>=n)break;
LL tmp=p[(i-1)*2]+1;
ans=(ans+tmp)%mod;
if(sum+sum/2<n){
ans=(ans+tmp)%mod;
ans=(ans+tmp*(((n-1-(sum+sum/2))/sum)%mod))%mod;
}
}
cout<<ans<<endl;
}
return 0;
}