P8569 [JRKSJ R6] 第七学区
Rainbow_qwq · · 题解
来写一下
首先要有一个
int n;
ull res,lst[66];
inline ull C2(int x){return 1ull*x*(x-1)/2;}
signed main()
{
READ::init(n);
ull sum=0;
int lim=0;
For(i,0,n-1){
ull x=READ::read();
sum+=(~x);
For(j,0,63)
if(x>>j&1)sum-=lst[j]<<j,lst[j]=0;
else ++lst[j];
res-=sum;
}
res-=C2(n+1);
cout<<res;
return 0;
}
用一个 trick,考虑原本我们维护的是 64 个
对于
小常数
int n;
ull res;
inline ull C2(int x){return 1ull*x*(x-1)/2;}
ull w[30];
signed main()
{
READ::init(n);
ull sum=0;
int lim=0;
For(i,0,n-1){
ull x=READ::read();
sum+=(~x);
// For(j,0,63)
// if(x>>j&1)sum-=lst[j]<<j,lst[j]=0;
// else ++lst[j];
ull up=(~x),nup;
for(int j=0;j<=lim;++j){
sum-=(w[j]&x)<<j;
w[j]&=(~x); // 上两行是变为 0 的操作
nup=up&w[j];
w[j]^=up;
up=nup; // 上三行是模拟 +1 的二进制加法器
}
if((i&-i)==i)++lim;
res-=sum;
}
res-=C2(n+1);
cout<<res;
return 0;
}