版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35649707/article/details/82814295
题解:
首先前缀异或处理一下,变成一堆数中两个异或为
。
显然这是一一对应的关系,如果一对数中两个都小于
个,直接暴力
解决。 否则在序列上
解决一对数。 时间复杂度
。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair <int,int> pii;
const int RLEN=1<<18|1;
inline char nc() {
static char ibuf[RLEN],*ib,*ob;
(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
char ch=nc(); int i=0,f=1;
while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
return i*f;
}
inline void W(int x) {
static int buf[50];
if(!x) {putchar('0'); return;}
if(x<0) {putchar('-'); x=-x;}
while(x) {buf[++buf[0]]=x%10; x/=10;}
while(buf[0]) {putchar(buf[buf[0]--]+'0');}
}
const int N=3e5+50, B=1500, mod=1073741824;
inline void add(int &x,int y) {x=(x+y>=mod) ? (x+y-mod) : (x+y);}
inline void dec(int &x,int y) {x=(x-y<0) ? (x-y+mod) : (x-y);}
inline int mul(int x,int y) {return (long long)x*y%mod;}
int n,m,k,tot;
int a[N],b[N],c[N],vis[N],tar[N];
int det[N];
vector <int> pos[N];
vector <pii> qry[N];
inline void init() {
n=rd(), m=rd(), k=rd();
for(int i=1;i<=n;i++) a[i]=rd()^a[i-1], c[++tot]=a[i], c[++tot]=k^a[i];
c[++tot]=0; c[++tot]=k;
sort(c+1,c+tot+1);
tot=unique(c+1,c+tot+1)-c-1;
for(int i=n;i>=1;i--) b[i]=a[i], a[i]=a[i-1];
for(int i=1;i<=n;i++) {
a[i]=lower_bound(c+1,c+tot+1,a[i])-c;
tar[i]=lower_bound(c+1,c+tot+1,k^b[i])-c;
b[i]=lower_bound(c+1,c+tot+1,b[i])-c;
pos[a[i]].push_back(i);
}
for(int i=1;i<=m;i++) {
int l=rd(), r=rd();
qry[r].push_back(pii(l,rd()));
}
}
const int S=400;
struct BL {
int id[N],bg[N],ed[N],h;
int tag[N],val[N];
inline void init() {
for(int l=1,r;l<=n;l=r+1) {
r=min(n,l+S);
bg[++h]=l; ed[h]=r;
for(int j=l;j<=r;j++) id[j]=h;
}
}
inline void add(int l,int v) {
if(id[l]==id[n]) for(int j=l;j<=n;j++) ::add(val[j],v);
else {
for(int t=id[l]+1;t<=h;++t) ::add(tag[t],v);
for(int i=l;i<=ed[id[l]];++i) ::add(val[i],v);
}
}
inline int ask(int pos) {return (val[pos]+tag[id[pos]])%mod;}
} bl;
inline void solve1() {
bl.init();
for(int i=n;i>=1;i--) {
for(int j=0;j<qry[i].size();++j) bl.add(qry[i][j].first,qry[i][j].second);
if(pos[tar[i]].size()>B) continue;
for(int j=0;j<pos[tar[i]].size();++j) {
int v=pos[tar[i]][j];
if(v>i) break;
int d=bl.ask(v);
add(det[v],d); dec(det[i+1],d);
}
}
}
int opt1[N];
vector <pii> opt2[N];
int cnt[N],sumr[N],sumw[N];
inline void solve(int L,int R) {
for(int i=0;i<=n+1;i++) sumw[i]=0;
for(int i=n;i>=1;i--) {
sumr[i]=(b[i]==R) ? opt1[i] : 0;
add(sumr[i],sumr[i+1]);
cnt[i]=(b[i]==R) ? 1 : 0;
cnt[i]+=cnt[i+1];
for(int j=0;j<opt2[i].size();++j) {
int c=cnt[i]-cnt[opt2[i][j].first+1];
add(sumw[i],(LL)c*opt2[i][j].second%mod);
}
add(sumw[i],sumw[i+1]);
if(a[i]==L) {
add(det[i],sumr[i]);
add(det[i],sumw[i+1]);
}
}
for(int i=1;i<=n;i++) {
cnt[i]=(a[i]==L) ? 1 : 0;
cnt[i]+=cnt[i-1];
if(b[i]==R) dec(det[i+1],(LL)cnt[i]*opt1[i]%mod);
}
for(int i=0;i<=n+1;i++) sumw[i]=0;
for(int i=1;i<=n;i++) for(int j=0;j<opt2[i].size();++j) {
pii &q=opt2[i][j];
add(sumw[i],(LL)cnt[i-1]*q.second%mod);
dec(sumw[q.first+1],(LL)cnt[i-1]*q.second%mod);
}
for(int i=1;i<=n;i++) {
add(sumw[i],sumw[i-1]);
if(b[i]==R) dec(det[i+1],sumw[i]);
}
}
inline void solve2() {
for(int i=1;i<=n;i++) for(int j=0;j<qry[i].size();++j) {
pii q=qry[i][j];
add(opt1[i],q.second);
if(q.first>1) opt2[q.first].push_back(pii(i,mod-q.second)), dec(opt1[q.first-1],q.second);
}
for(int i=n;i>=1;i--) add(opt1[i],opt1[i+1]);
for(int i=1;i<=n;i++)
if(pos[tar[i]].size()>B && !vis[tar[i]])
vis[tar[i]]=1, solve(tar[i],b[i]);
}
int main() {
init();
solve1();
solve2();
for(int i=1;i<=n;i++) add(det[i],det[i-1]), W(det[i]), putchar(' ');
}