题目链接:https://codeforces.com/contest/1151/problem/C
解题心得: 我是直接跟着题目模拟的,写起来很复杂的样子,有好多东西容易模拟时忽略,反正我写得超级暴力,看见有大佬代码很短,很优雅。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
ll l, r, flag = 1, odd, even;
ll mul(ll x, ll y) {//看到ab都是1e18防止数据溢出
x %= mod;
y %= mod;
ll ans = 0;
while (y) {
if (y & 1) ans += x;
x += x;
x %= mod;
ans %= mod;
y >>= 1;
}
return ans;
}
ll qpow(ll x , ll y) {//在等差公式求和中除2用逆元
ll ans = 1;
while(y) {
if(y&1) ans *= x;
x *= x;
x %= mod;
ans %= mod;
y>>=1;
}
return ans;
}
int main() {
// freopen("1.in", "r", stdin);
scanf("%lld%lld", &l, &r);
ll sum = 0, len = 1, ans = 0;
//flag=1奇数项加,flag=0偶数项加
while (sum < r) {
ll odd2 = odd, even2 = even;
if (flag) odd += len;
else even += len;
odd %= mod;
even %= mod;
sum += len;//总的长度
if(sum < l) {//小于l
len <<= 1;
flag = !flag;
continue;
}
if (sum - len < l) {//l在len中间
ll len2 = min(sum, r) - l + 1;
if (flag) {
odd2 += len - (sum-l+1);
ans += mul(mul(len2 , (mul(odd2 , 2) + 1 + mul((odd2 + len2 - 1) , 2) + 1)), qpow(2, mod-2));
} else {
even2 += len - (sum-l+1);
ans += mul(mul(len2 , (mul(even2 + 1, 2) + mul((even2 + len2) , 2))) , qpow(2, mod-2)) ;
}
} else if (sum > r) {//r在len中间
ll len2 = len - (sum - r);
if (flag)
ans += mul(mul(len2 , (odd2 * 2 + 1 + (odd2 + len2-1) * 2 + 1)),qpow(2, mod-2));
else
ans += mul(mul(len2, ((even2 + 1) * 2 + (even2 + len2) * 2)), qpow(2, mod-2));
} else {//len在l和r中间
if (flag)
ans += mul(mul(len , (odd2 * 2 + 1 + (odd2 + len-1) * 2 + 1)), qpow(2, mod-2)) ;
else
ans += mul(mul(len , ((even2 + 1) * 2 + (even2 + len) * 2)), qpow(2, mod-2)) ;
}
ans %= mod;
len <<= 1;
flag = !flag;
}
printf("%lld\n", ans);
return 0;
}