题目链接
题意
有
n
个点,
思路
首先,
0
到
其次,对于任意一个
i
,
这样割,肯定有一个点为分界线(
100…0
),前面的所有点与
n−1
连通而不与
0
连通,后面的所有点与
现在的问题就是怎么求割下来的各条边的流量和。
当
i
的最高位为
当
i
的最高位为
对于这些数,其
j−1
到
0
位与
Code
#include <bits/stdc++.h>
typedef long long LL;
const LL mod = 1e9+7;
LL n;
void work() {
if (n == 2) { printf("1\n"); return;}
--n;
int len = 0;
LL nn = n;
while (nn) ++len, nn >>= 1;
LL ans = (1LL << (len-2)) % mod * (((1LL << (len-1)) - 1 + mod) % mod) % mod;
(ans += n) %= mod;
for (int i = 0; i < len-1; ++i) {
if (n & (1LL << i)) {
if (i == 0) (ans += 1) %= mod;
else (ans += (((3LL << i) % mod - 1 + mod) % mod * ((1LL << (i-1)) % mod)) % mod) %= mod;
}
}
printf("%lld\n", ans);
}
int main() {
while (scanf("%lld", &n) != EOF) work();
return 0;
}