• 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
    ",ans);
    30 return 0;
    31 }
  • 相关阅读:
    ZOJ 3556
    ZOJ 2836
    HDU 2841
    HDU 4135
    POJ 3695
    POJ 2773
    HDU 4407
    HDU 1796
    ZOJ 3688
    ZOJ 3687
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10981826.html
Copyright © 2020-2023  润新知