被卡常到80分的异或粽子
本人自闭
常年不码题常数巨大。。。
#include<bits/stdc++.h> #define ll long long #define ui unsigned int using namespace std; const int N=500000,M=N*33+5; inline ui read(){ ui x=0; char ch=getchar(); for(;!isdigit(ch);ch=getchar()); for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x; } ui n,k,L,R,mid,num=1,c[67],A; ui ch[M][2],sum[M],ans,a[N+5]; ll tot,tt; inline void ins(ui x){ ui now=1,u; sum[1]++; for(int i=31;i>=0;now=ch[now][u],sum[now]++,i--){ u=(x&c[i])>0; if(!ch[now][u]) ch[now][u]=++num; } } /* x ^ a[i] >= mid */ inline bool check(){ ll now=0; for(ui i=0,p,u;i<=n;i++){ p=1; for(int j=31;p&&j>=0;j--){ u=(a[i]&c[j])>0; if(mid&c[j]) p=ch[p][u^1]; else now+=sum[ch[p][u^1]],p=ch[p][u]; } now+=sum[p]; if(now>=k*2) return 1; } return 0; } /* A ^ now >= ans */ void Get(int p,int l,ui now,ui alr){ if((A^now)<alr) return; if(l<0){ tt+=sum[p],tot+=sum[p]*(ll)(A^now); return;} alr+=c[l]&ans; if(ch[p][0]) Get(ch[p][0],l-1,now,alr); if(ch[p][1]) Get(ch[p][1],l-1,now+c[l],alr); } inline void solve(){ L=0,R=(1<<32ll)-1; while(L<=R){ mid=L+(ll)R>>1; if(check()) ans=mid,L=mid+1; else R=mid-1; } for(int i=0;i<=n;i++) A=a[i],Get(1,31,0,0); } int main(){ // freopen("data.in","r",stdin); // freopen("data.out","w",stdout); // cout<<clock()<<endl; c[0]=1; for(int i=1;i<=31;i++) c[i]=c[i-1]+c[i-1]; n=read(),k=read(),ins(0); for(int i=1;i<=n;i++) a[i]=a[i-1]^read(),ins(a[i]); solve(),tot>>=1,tt>>=1; // cout<<ans<<endl; printf("%lld\n",tot-ans*(ll)(tt-k)); // cout<<clock()<<endl; return 0; }
我爱学习,学习使我快乐