【推導】【線段樹】hdu5929 Basic Data Structure
阿新 • • 發佈:2017-11-23
mat string 發現 span print 定義 %d ram 個數
題意:
維護一個棧,支持以下操作:
從當前棧頂加入一個0或者1;
從當前棧頂彈掉一個數;
將棧頂指針和棧底指針交換;
詢問a[top] nand a[top-1] nand ... nand a[bottom]的值。
nand是這樣定義的:
?? 0 nand 0 = 1
?? 0 nand 1 = 1
?? 1 nand 0 = 1
?? 1 nand 1 = 0
關鍵是要發現性質,任何數nand 0,都會變成1。反復nand上1的話,則值會交替變化。
所以假設當前棧頂在左側,只需要找到最右側的0的位置,然後按照其右側1的數量的奇偶性輸出零或者一即可(如果最右側的0在最左端,則其右側有奇數個1就輸出1,否則輸出零。如果最右側的零不在最左端,則其右側有奇數個1就輸出零,否則輸出1)。
棧頂在右側的情況同理。
用線段樹維護。
#include<cstdio> #include<cstring> using namespace std; bool hav[400005<<2]; int a[400005]; int T,m,n,e[2]; void update(int p,int v,int rt,int l,int r){ if(l==r){ if(v==0){ hav[rt]=1; } else{ hav[rt]=0; } return; } int m=(l+r>>1); if(p<=m){ update(p,v,rt<<1,l,m); } else{ update(p,v,rt<<1|1,m+1,r); } hav[rt]=(hav[rt<<1] || hav[rt<<1|1]); } int find1(int rt=1,int l=1,int r=n){ if(l==r){ return l; } int m=(l+r>>1); if(hav[rt<<1]){ return find1(rt<<1,l,m); } else{ return find1(rt<<1|1,m+1,r); } } int find2(int rt=1,int l=1,int r=n){ if(l==r){ return l; } int m=(l+r>>1); if(hav[rt<<1|1]){ return find2(rt<<1|1,m+1,r); } else{ return find2(rt<<1,l,m); } } int main(){ //freopen("h.in","r",stdin); int x; bool dir=0; char op[10]; scanf("%d",&T); memset(a,-1,sizeof(a)); for(int zu=1;zu<=T;++zu){ printf("Case #%d:\n",zu); scanf("%d",&m); e[0]=m; e[1]=m+1; n=2*m; for(int i=1;i<=m;++i){ scanf("%s",op); if(op[2]==‘S‘){ scanf("%d",&x); if(!dir){ a[e[0]]=x; update(e[0],x,1,1,n); --e[0]; } else{ a[e[1]]=x; update(e[1],x,1,1,n); ++e[1]; } } else if(op[2]==‘P‘){ if(!dir){ ++e[0]; a[e[0]]=-1; update(e[0],-1,1,1,n); } else{ --e[1]; a[e[1]]=-1; update(e[1],-1,1,1,n); } } else if(op[2]==‘V‘){ dir^=1; } else{ if(e[0]==e[1]-1){ puts("Invalid."); continue; } if(hav[1]){ if(!dir){ int p=find2(); if(p==e[0]+1){ puts((e[1]-p-1)%2==1 ? "1" : "0"); } else{ puts((e[1]-p-1)%2==1 ? "0" : "1"); } } else{ int p=find1(); if(p==e[1]-1){ puts((p-e[0]-1)%2==1 ? "1" : "0"); } else{ puts((p-e[0]-1)%2==1 ? "0" : "1"); } } } else{ puts((e[1]-e[0]-1)%2==1 ? "1" : "0"); } } } memset(a,-1,sizeof(int)*(n+1)); memset(hav,0,sizeof(bool)*(n*4+1)); } return 0; }
【推導】【線段樹】hdu5929 Basic Data Structure