C. Problem for Nazar(数学)

 题目链接:

https://codeforces.com/contest/1151/problem/C

题目大意:

一开始第一行是 1,第二行是2 4 ,第三行是3 5 7 9 ,类似这样下去,每一行的个数是上一行的个数,然后对这些点从第一个进行编号,问你从[l,r]区间数的和。

具体思路:

我们可以先求出前l-1个的总和,然后再求出前r个的总和,这两部分做差就是最终答案。

然后具体每一次计算的时候,按照题目描述的求出前n个有多少个奇数,有多少个偶数。

前m个奇数的和是(m^2),前m个奇数的和是(m*(m+1))。

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 # define ll long long
 4 const int maxn = 2e5+100;
 5 const ll mod = 1e9+7;
 6 ll solve(ll pos){
 7 ll ans=0;
 8 ll num_even=0;
 9 ll num_odd=0;
10 int type=0;
11 for(ll i=1;i<=pos;i*=2){
12 ll num=min(i,pos-ans);// 防止计算最后一块区域的时候算多了
13 ans+=i;
14 if(!type)num_even+=num;
15 else num_odd+=num;
16 type^=1;
17 }
18 num_even%=mod;
19 num_odd%=mod;
20  ans=(num_even*num_even%mod)+(num_odd*(num_odd+1ll)%mod);
21 ans%=mod;
22 return ans;
23 }
24 int main(){
25 ll l,r;
26 scanf("%lld %lld",&l,&r);
27 ll ans=solve(r)-solve(l-1);
28 while(ans<0)ans+=mod;
29 printf("%lld\n",ans);
30 return 0;
31 }

猜你喜欢

转载自www.cnblogs.com/letlifestop/p/10981826.html