1. 程式人生 > >BZOJ5220: [Lydsy2017省隊十連測]異或與區間加

BZOJ5220: [Lydsy2017省隊十連測]異或與區間加

傳送門

題解: 首先字首異或處理一下,變成一堆數中兩個異或為kk。 顯然這是一一對應的關係,如果一對數中兩個都小於n\sqrt{n}個,直接暴力O(nn)O(n\sqrt{n})解決。 否則在序列上O(n)O(n)解決一對數。 時間複雜度O(nn)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(' '); }