CodeForces 1151C数学+快速乘

奇偶性质+快速乘
hint:真的太菜了,昨天个人训练赛的时候憋了三个小时,还是没推出来,B题和D题连读都没读,感觉应该能做的,但一心想把这个数学题做出来,,最后直接憋死了。哎,还是要继续努力鸭。
题意:存在一个按顺序存储无限多个偶数的集合和一个按顺序存储奇数的集合,则存在一个数k=0,先在奇数集合中取1<<k个数,k++,然后再从偶数集合中取1<<k个数,k++,之后循环此操作。即可得到一个序列。现有long long int 范围内的两个数l,r;求上述序列中l与r下标之间的数的sum。
正解:前n个奇数的sum=n x n,前n个偶数的sum=n x n+1;则统计前l-1和前r个数中奇数和偶数的个数,求sum后做差即可得到ans;
注意,n*n会爆long long int,故须采用快速乘来求解。

AC代码如下:

#include <bits/stdc++.h>
#define FOPI freopen("INPUT.TXT", "r", stdin)
#define DOPI freopen("OUTPUT.TXT", "w", stdout)
#define FOR(i, x, y) for(int i = x; i <= y; i ++)
#define ROF(i, x, y) for(int i = x; i >= y; i --)
using namespace std;
typedef long long int ll;
const int ind=0x3f3f3f3f,N=1e6+10;
const ll inlld=0x3f3f3f3f3f3f3f3f,mod=1e9+7;
ll mul(ll a,ll b)
{
    ll ans=0;
    while(b){
        if(b&1) ans=(ans+a)%mod;
        a=(a+a)%mod;
        b>>=1;
    }
    return ans;
}
ll getans(ll a)
{
    ll num=0,odd=0,even=0;
    while(a>0){
        if(!(num%2))odd+=min(a,(ll)1<<num);
        else even+=min(a,(ll)1<<num);
//        num++;
        a-=(ll)1<<num;
        num++;
    }
    return (mul(odd,odd)+mul(even,even+1)+mod)%mod;
}
int main()
{
    ios::sync_with_stdio(false);
    ll l,r;cin>>l>>r;
    cout <<(getans(r)-getans(l-1)+mod)%mod<<endl;
    return 0;
}
/*
88005553535 99999999999
761141116
5 14
105
1 3
7
*/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值