標籤:log span fine closed inline code 首碼 表示 class
4333: JSOI2012 智者的考驗Time Limit: 10 Sec Memory Limit: 256 MB
Submit: 68 Solved: 18
[Submit][Status][Discuss]Description公元1371年,太祖下令在北極閣上大建廟宇,短短几年,雞籠山上便建成了帝王廟、關公廟、真武廟、功臣廟、蔣王廟、都城隍廟、卞壺廟、忠烈廟、劉越王廟、曹武惠王廟共十座廟宇,統稱為“十廟”。 後來,為了方便人們來雞籠山進香禮佛,太祖下令疏通了雞籠山下已淤塞多年的潮溝。於是,便有了“進香河”。 然而並不是所有人都可以來雞籠山的,太祖在進香河上修建了一座石橋,中間懸掛了一塊高Rx寬Ry的機關格圖(如所示)。所有格子都是活動可翻轉的,一面是白色,一面是黑色,這裡我們用0表示白色,用1表示黑色。初始情況下,所有格子都是白色面朝前的。有Rx+Ry個機關按鈕,對應Rx行和Ry列。一個按鈕一旦觸發,就會引發對應的一行或一列的格子同時翻轉。 同時,善於識天象的謀臣劉基給出了一種黑白狀態,稱之為“厄運星”。每一位過往前去雞籠山的人都需要觸發且只觸發一個按鈕,觸發後,如果來訪者呈“厄運星”形狀,則不允許通過。 每一天要來雞籠山的人數N是事先就知道的,同時天朝神威浩蕩,每一位來者一開始總是有很大機率觸發編號為1的按鈕,我們不妨用數列A1,A2,…,AN來表示,問題保證了初始時候的A數列全為1。同時在整個問題中,Ai滿足1<=Ai<=Rx+Ry。太祖很關心那些不允許去雞籠山的人數。於是他時不時就會詢問關於“某一段時間內會有多少人不能通過“厄運星”的考驗”。然而那些前來雞籠山的文人墨客並不願意如此單一的操作。來訪者有可能會突然決定修改自己的觸發按鈕。更麻煩的情況,結伴而來的連續若干人會突然決定修改觸發按鈕並且都去觸發同一個按鈕。 現在這麻煩的問題交給了你。 後記: 等到了乾隆時期,一位人稱紀昀的才子來訪此地,告訴了人們一套方法,從此再也沒有人會不被允許通過了。久而久之,雞籠山煙火依舊,然這機關格圖的故事便漸漸失傳了。直到今天才再一次被世人所瞭解。
Input輸入檔案第一行有2個數字Rx和Ry表示機關格圖的高和寬()。之後Rx行每一行Ry個數字,描述了“厄運星”形狀,每一個數字都滿足非0即1. 之後一行有兩個數字,分別為N和M,表示人數和詢問修改的次數。 之後M行,對應M次詢問或修改。每一行先有一個數字t: 若t為0:之後有2個數字d和x,表明將Ad修改為x。 若t為1:之後有2個數字l和r,表明詢問第l個人到第r個人中有多少人觸發按鈕後會出現“厄運星”形狀,從而無法通過。若t為2:之後有3個數字l,r和x,表面將Al,Al+1,…,Ar-1,Ar都修改為x。
Output對於每一次詢問(即t為1的情況),輸出單獨一行,一個整數描述了在區間[l,r]中滿足要求的人數。
Sample Input2 3
0 0 1
1 1 0
7 4
1 1 7
0 2 3
0 3 4
1 1 7 Sample Output0
3 (有時候還是覺得複製一下題面挺好的問題顯然可以轉化成帶修地查詢區間內首碼異或和為給定數的數量。嗯?好像有64種狀態?不對不對,5個按鈕應該是2^5=32種狀態?哦,把所有按鈕都取反跟原來是一樣,那就是2^4=16種狀態。那就可做了!區間修改為某個數的影響最多隻有1次(兩兩抵消)。線段樹上打打標記就可以了(我怎麼還寫了一早上啊)
#include<cstdio>#include<cstring>#include<algorithm>#define MN 1000001using namespace std;int read_p,read_ca;inline int read(){ read_p=0;read_ca=getchar(); while(read_ca<‘0‘||read_ca>‘9‘) read_ca=getchar(); while(read_ca>=‘0‘&&read_ca<=‘9‘) read_p=read_p*10+read_ca-48,read_ca=getchar(); return read_p;}struct na{int c[16],sum,l,r,y,a,Q,V;}t[MN<<1];int n,m,q,rx,ry,o[10],s[16],to[16][10],num=0,bo,ro=0,x,N[64];void build(int &p,int l,int r){ if (p==0) p=++num,t[p].l=t[p].r=t[p].sum=t[p].y=0,t[p].a=-1; t[p].c[N[0]]=((r-l)>>1)+(!(l&1)||!(r&1)); t[p].c[N[o[0]]]=((r-l)>>1)+((l&1)||(r&1));t[p].sum=((((r-l)>>1)+((l&1)||(r&1)))&1)*o[0]; if (l==r) return; int mid=l+r>>1; build(t[p].l,l,mid);build(t[p].r,mid+1,r);}void pd(int p,int l,int r){ if (t[p].a!=-1){ if (t[p].l) t[t[p].l].a=t[p].a,t[t[p].l].V=t[p].V,t[t[p].l].Q=t[p].Q,t[t[p].l].y=0; if (t[p].r) t[t[p].r].a=t[p].a,t[t[p].r].V=t[p].V,t[t[p].r].Q=t[p].Q,t[t[p].r].y=0; memset(t[p].c,0,sizeof(t[p].c)); t[p].c[N[t[p].V]]=((r-l)>>1)+(!(l-t[p].Q&1)||!(r-t[p].Q&1)); t[p].c[N[t[p].a^t[p].V]]=((r-l)>>1)+((l-t[p].Q&1)||(r-t[p].Q&1));t[p].sum=((((r-l)>>1)+((l-t[p].Q&1)||(r-t[p].Q&1)))&1)*t[p].a^((r-l+1&1)*t[p].V); t[p].a=-1; }}void up(int p,int l,int r){ int mid=l+r>>1; pd(t[p].l,l,mid);pd(t[p].r,mid+1,r); t[p].sum=t[t[p].l].sum^t[t[p].r].sum^(((mid-l+1)&1)*t[t[p].l].y)^(((r-mid)&1)*t[t[p].r].y); for (int i=0;i<16;i++) t[p].c[i]=t[t[p].l].c[N[s[i]^t[t[p].l].y]]+t[t[p].r].c[N[s[i]^t[t[p].r].y]];}void cg(int p,int l,int r,int po,int v){ if (po<=l) t[p].y^=v;else{ pd(p,l,r); int mid=l+r>>1; cg(t[p].r,mid+1,r,po,v); if (mid>=po) cg(t[p].l,l,mid,po,v); up(p,l,r); }}int ask(int p,int l,int r,int po){ if (t[p].a!=-1) return (t[p].a*(po-t[p].Q&1))^t[p].V^t[p].y; if (l==r) return t[p].sum^t[p].y; int mid=l+r>>1; if (po<=mid) return ask(t[p].l,l,mid,po)^t[p].y;else return ask(t[p].r,mid+1,r,po)^t[p].y;}int que(int p,int l,int r,int L,int R,int v){ pd(p,l,r); v^=t[p].y; if (L==l&&R==r) return t[p].c[N[v]]; int mid=l+r>>1; if (R<=mid) return que(t[p].l,l,mid,L,R,v);else if (L>mid) return que(t[p].r,mid+1,r,L,R,v);else return que(t[p].l,l,mid,L,mid,v)+que(t[p].r,mid+1,r,mid+1,R,v);}void ca(int p,int l,int r,int L,int R,int v,int V,int Q){ if (L==l&&R==r){ t[p].a=v;t[p].V=V;t[p].y=0;t[p].Q=Q; t[p].c[N[V]]=((r-l)>>1)+(!(l-Q&1)||!(r-Q&1)); t[p].c[N[v^V]]=((r-l)>>1)+((l-Q&1)||(r-Q&1));t[p].sum=(((((r-l)>>1)+((l-Q&1)||(r-Q&1)))&1)*v)^((r-l+1&1)*V); }else{ pd(p,l,r);V^=t[p].y; int mid=l+r>>1; if (R<=mid) ca(t[p].l,l,mid,L,R,v,V,Q);else if (L>mid) ca(t[p].r,mid+1,r,L,R,v,V,Q);else ca(t[p].l,l,mid,L,mid,v,V,Q),ca(t[p].r,mid+1,r,mid+1,R,v,V,Q); up(p,l,r); }}int main(){ register int i,j; rx=read();ry=read();n=0; for (i=0;i<rx;i++) for (j=0;j<ry;j++) o[i]^=1<<(i*ry+j),o[j+rx]^=1<<(i*ry+j),q^=read()<<(i*ry+j); n=read();m=read(); s[bo=num=0]=0; for(;bo<=num;){ for (i=0;i<rx+ry;i++){ for (j=0;j<=num;j++) if (s[j]==(s[bo]^o[i])) break; if (j>num) s[++num]=s[bo]^o[i]; to[bo][i]=j; } bo++; } for (i=0;i<64;i++) N[i]=-1; for (i=0;i<=num;i++) N[s[i]]=i; num=0; build(ro,1,n); while (m--){ bo=read(); if (bo==0) bo=read(),cg(ro,1,n,bo,o[read()-1]^ask(ro,1,n,bo)^(bo==1?0:ask(ro,1,n,bo-1)));else if (bo==1) if (bo=read(),x=read(),N[q]==-1) puts("0");else printf("%d\n",que(ro,1,n,bo,x,q));else if (rx=read(),ry=read(),x=o[read()-1],cg(ro,1,n,ry+1,ask(ro,1,n,ry)^(((ry-rx+1)&1)*x)),ca(ro,1,n,rx,ry,x,0,rx-1),rx-1) cg(ro,1,n,rx,ask(ro,1,n,rx-1)); }}View Code
BZOJ:4333: JSOI2012 智者的考驗