原题链接:D-小蓝的二进制询问
题意:思路:对于从[l,r]上的数,可以先算出从[0,r]的所有二进制1然后减去[0,l]的所有二进制1。思考如何计算,从样例中给出的5来思考,[0,5]的二进制表示分别为:000,001,010,011,100,101。可以发现二进制的最后一位循环的是01,倒数第二位循环的就是0011,根据二进制数的性质就可以知道,每一位的二进制循环长度是2的次方。分别计算每一位二进制1的数量累加即可。、
//冷静,冷静,冷静
//调不出来就重构
#pragma GCC optimize(2)
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pii;
const int N=1e6+10,mod=998244353;
ll p[N];
int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);ll t;cin>>t;p[0]=1;for(int i=1;i<=61;i++){p[i]=p[i-1]*2ll;//计算出2次方数,这个数在下面会被用作除数,并且2的61次方不会爆longlong,所以不取模 }while(t--){ll l,r;cin>>l>>r;ll ans=0;r++;//计算的是从0开始的,计算的是l-1,然后因为从0开始所以需要+1,所以l不变 for(int i=1;i<=61;i++){ll v=l/p[i],w=r/p[i];//有多少个二进制循环 ll v1=l%p[i],w1=r%p[i];//不完整的二进制循环有几个数 ans=(ans+w%mod*p[i-1]%mod-v%mod*p[i-1]%mod+mod)%mod;//完整循环二进制1的差值 ans%=mod;v1=max(0ll,v1-p[i-1]);w1=max(0ll,w1-p[i-1]);//看看多余的数,有没有大于当前位循环的一半 ans=((ans+w1)%mod-v1%mod+mod)%mod;//计算多余的 ans%=mod;}cout<<ans%mod<<endl;}return 0;
}