本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题意:
给你一个n,求n分别模上1到n之后相或的值
思路:
由或的性质可以得知:只需要找到所有模数在二进制位上出现的1的并集即可(并且对于同一模数,多个该模数和单个该模数对答案的贡献一样),而对于此题来说,我们肯定可以在模数中找到一个从1开始且公差为1的等差数列,因而我们只需要找到模数的最大值,就可以得出答案。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll a[100];
int main()
{
int t;
cin>>t;
for(int i = 1; i <= 60; i++)
{
a[i] = pow(2,i-1);
}
while(t--)
{
ll n;
cin>>n;
int cnt = 0;
ll now = 1;
for(int i = 1; i <= 64; i++)
{
now *= 2;
if(now >= n)
{
cnt = i-1;
break;
}
}
ll ans = 0;
for(int i = 1; i <= cnt; i++)
{
ans += a[i];
}
cout<<ans<<endl;
}
}