注意要把1转为ll !!!
本来是一个美好的下午的,但让这题毁了,当然主要是因为我是sb
如果按照题意去模拟的话那直接T上天,一开始我以为只要是两个数不相等,他们的异或就不会等于a[i],从这里我就是个sb了,因为x可以比a[i]大,只要a[i]的1 x都有,那么x&a[i]=a[i],所以我这个sd思路就挂了;我们可以反着想一下,假设一开始二进制位(一开始有k位)都是空的,可以放0也可以放1,我们找x&a[i]=a[i]满足条件的i,比如a[1]的二进制是000011100,那原来的空位就被填成了000011100,这些0可以放0也可以放1,那么a[1]的贡献就是2的9次方-2的6次方(k=9,0剩下6个),再往下一直找,找到了a[i],a[i-1]的时候还剩下d个0,到了a[i-1]还剩下e个0,那a[i]的贡献就是(2的d次方-2的e次方)*i;仔细想一想就懂了,脑子已经垮掉了,说的好像不是很清楚
函数求和 - 题目 - Daimayuan Online Judge
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll qpow(ll a,ll b){
ll res=1;
while(b){
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
ll n,k,a[100005],b[105];
int main(){
//freopen("in.txt","r",stdin);
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
ll cnt=k,fr=(1LL<<k),ans=0;//不要忘了要把1转化为ll的形式,fr不用取模,不然会出负值
for(int i=1;i<=n;i++){
for(int j=0;j<=k;j++){
if((a[i]>>j)&1){
if(!b[j]) b[j]=1,cnt--;
}
}
ll ccnt=(1LL<<cnt);
ans=(ans+(fr-ccnt)*i%mod)%mod;
fr=ccnt;
}
cout<<ans<<endl;
return 0;
}