bzoj 4017 小Q的无敌异或

来源:互联网 发布:数码淘宝店铺简介 编辑:程序博客网 时间:2024/04/28 16:46

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>

#define md 998244353
#define ll long long
#define inf (int) 1e9
#define eps 1e-8
#define N 1000010
using namespace std;
int a[N],xr[N],s[2];
bool c[2*N];
ll sum[N];
int n;
struct data{ ll x; int id; }p[N];
bool cmp(data a,data b) { return a.x<b.x;}
int find(ll x)
{
int l=0,r=n;
while (l!=r)
{
//printf("%d %d %lld %lld\n",l,r,p[(l+r)>>1].x,x);
int mid=(l+r+1)>>1;
if (p[mid].x<=x) l=mid; else r=mid-1;
}
//printf("find: %lld %d %lld\n",x,l,p[l].x);
return l;
}
void add(int x)
{
if (!x) return;
for (;x<=n;x+=x&(-x)) c[x]^=1;
}
int qsum(int x)
{
int sum=0;
for (;x;x-=x&(-x)) sum^=c[x];
return sum;
}
int main()
{
scanf("%d",&n); n++; a[1]=0;
for (int i=2;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
xr[i]=xr[i-1]^a[i];
}
ll f=0;
for (int k=0;k<=30;k++)
{
int tot=0; ll now=1<<k;
s[0]=s[1]=0;
for (int i=1;i<=n;i++)
{
int x=(xr[i]>>k)&1;
tot+=s[x^1]; if (tot>=md) tot-=md;
s[x]++;
}
f=(f+now*tot)%md;
//printf("%d %d %d\n",s[0],s[1],tot);
}
printf("%lld ",f);
ll g=0;
for (int k=0;(sum[n]>>k)>0;k++)
{
ll m=(ll)1<<k,m2=m<<1;
memset(c,0,sizeof(c));
for (int i=1;i<=n;i++)
{
p[i].x=sum[i]%m2;
p[i].id=i;
}
sort(p+1,p+n+1,cmp);
bool opt=0;
for (int i=1;i<=n;i++)
{
ll now=sum[i]%m2;
opt^=qsum(find(now-m))^qsum(find(now+m))^qsum(find(now));
add(find(now));
}
if (opt) g|=((ll)1<<k);
}
printf("%lld\n",g);
return 0;
}



0 0