CF1151C 题解

思路

根据等差数列求和公式,1+3+5++(2n1)=(2n1+1)×n2=n2,2+4+6++2n=(2n+2)×n2=n×(n+1)1+3+5+\dots+(2n-1)=\frac{(2n-1+1)\times n}2=n^2,2+4+6+\dots+2n=\frac{(2n+2)\times n}2=n\times(n+1)。所以对于求 f(s)f(s)(前 1s1\sim s 个数的和),我们只要枚举每一轮,统计奇偶共有几个数并直接求和即可。最后求 lrl\sim r 个数,只需要差分求 f(r)f(l1)f(r)-f(l-1) 即可。

代码

# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair <int, int> pii;
const ll mod = 1e9 + 7;
ll l, r;
int i;
ll f (ll x) {
	ll sum1 = 0, sum2 = 0;
	for (i = 0; i < 63; x -= 1ll << i, ++ i)
		if (1ll << i > x) {
			if (i & 1)
				sum2 += x;
			else
				sum1 += x;
			break ;
		} else if (i & 1)
			sum2 += 1ll << i;
		else
			sum1 += 1ll << i;
	sum1 %= mod, sum2 %= mod;
	return (sum1 * sum1 + sum2 * (sum2 + 1)) % mod;
}
int main () {
	ios::sync_with_stdio (0);
	cin.tie (0);
	cout.tie (0);
	cin >> l >> r;
	cout << ((f (r) - f (l - 1)) % mod + mod) % mod;
	return 0;
}
posted @ 2024-05-30 14:06  Vitamin_B  阅读(26)  评论(0)    收藏  举报  来源