題目:http://acm.hdu.edu.cn/showproblem.php?pid=5929
題意:
維護一個棧,支援往棧裡塞 0/1 ,彈棧頂,翻轉棧,詢問從棧頂到棧底按順序 NAND 的值。
分析:
【題解】只要知道最後的 000 後面 111 的個數的奇偶性就行。可以用鏈表把所有 000 的位置存下來。
思路基本和題解一樣,都是先把0的位置儲存起來,然後做相應的判斷
這題的關鍵是怎麼快速的求出從棧頂到棧底的與非值
∙ 0 nand 0 = 1
∙ 0 nand 1 = 1
∙ 1 nand 0 = 1
∙ 1 nand 1 = 0
可以看出任何數跟0的與非值都是1,所以只要知道最後一個0位置就行了,因為前面所有數到0後與非值都是1,這樣再看一下0後面有幾個1就行了。
數組類比一下即可。
代碼:
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N = 4e5+10;int a[N];char op[11];int main() { //freopen("f.txt","r",stdin); int n,x,T; scanf("%d",&T); for(int cas=1; cas<=T; cas++) { scanf("%d",&n); printf("Case #%d:\n",cas); int cl=2e5+1,cr=2e5,l=cl,r=cr; memset(a,-1,sizeof(-1)); int flag=1; //1往右走,0往左走 while(n--) { scanf("%s",op); if(op[0]=='P') { if(op[1]=='O') { //pop if(flag) { --cr; if(~a[r]&&a[r]>cr)--r; } else { ++cl; if(~a[l]&&a[l]<cl)++l; } } else { //push scanf("%d",&x); if(flag) { if(x==0)a[++r]=++cr; else ++cr; } else { if(x==0)a[--l]=--cl; else --cl; } } } else if(op[0]=='Q') { //query if(cr<cl)puts("Invalid."); else if(r<l) { if((cr-cl+1)&1)puts("1"); else puts("0"); } else if(flag) { if(a[l]==cr) { if((a[l]-cl+1)&1)puts("0"); else puts("1"); } else if((a[l]-cl+1)&1)puts("1"); else puts("0"); } else { if(a[r]==cl) { if((cr-a[r]+1)&1)puts("0"); else puts("1"); } else if((cr-a[r]+1)&1)puts("1"); else puts("0"); } } else flag^=1; //reverse } } return 0;}