BZOJ5220: [Lydsy2017省队十连测]异或与区间加

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35649707/article/details/82814295

传送门

题解:
首先前缀异或处理一下,变成一堆数中两个异或为 k k
显然这是一一对应的关系,如果一对数中两个都小于 n \sqrt{n} 个,直接暴力 O ( n n ) O(n\sqrt{n}) 解决。 否则在序列上 O ( n ) O(n) 解决一对数。 时间复杂度 O ( n n ) O(n\sqrt{n})

#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(' ');
}

猜你喜欢

转载自blog.csdn.net/qq_35649707/article/details/82814295
今日推荐