Codeforces Round #553 (Div. 2) C. Problem for Nazar

题目链接: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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值