Codeforces Round #553 (Div. 2) C. Problem for Nazar 模拟+思维
题目链接
题意:给你给无限长的序列 A,让你求出 ∑i=lrAi.
思路:转化一下,即求 ∑i=1rAi−∑i=1l−1Ai。那么问题就好解决了,不断的倍增加上当前段的贡献,最后去掉多余的即可。
#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mp make_pair
#define pb push_back
using namespace std;
const int N = 2e5 + 11;
const LL mod = 1e9 + 7;
LL l, r, now = 1, sta, A, B;
LL odd, even;
LL get(LL g)
{
A = B = 0;now = sta = 1;odd = even = 0;LL ans=0;
while(1){
if(sta)ans+=(now/2)%mod*((B+now/2)%mod)%mod;
else ans+=(now/2)%mod*((A+now/2)%mod)%mod;
if(sta)B+=now;
else A+=now;
if(now>g)break;
now*=2;
sta^=1;
}
now--;
sta^=1;
if(sta)ans-=(now-g)%mod*((A-(now-g)+mod)%mod)%mod;
else ans-=(now-g)%mod*((B-(now-g)+mod)%mod)%mod;
return (ans+mod)%mod;
}
int main()
{
ios::sync_with_stdio(false);
cin >> l >> r;
cout << (get(r) - get(l - 1) + mod) % mod << endl;
return 0;
}