// hdu 5929 Basic Data Structure 類比// 題目連結:// http://acm.hdu.edu.cn/showproblem.php?pid=5929// 題目大意:// 有這樣一個棧,棧中只放入0或者1,有四種操作// 1)PUSH 1 or 0// 2)POP: 彈出棧頂元素// 3)REVERSE: 將棧中元素逆序// 4)QUERY: 查詢stack[top] nand stack[top-1]... nand stack[0];// 注:// 0 nand 0 = 1// 0 nand 1 = 1// 1 nand 0 = 1// 1 nand 1 = 0// 解題思路:// 首先注意到有0的時候,結果一定是1,重要性質.我們只要搞定距離棧底的// 最近的0以及之後1的個數就好// 其次對於REVERSE,我們可以用一個雙端棧,設定一個標量,就可以解決// 感悟:// 亮點就是用雙端棧的結構了,其次是細節的考慮,還算簡單,熟悉棧的操作// 並不難寫.繼續奮鬥^_^#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int MAXN = 2e5 + 8;const int ZERO = 2e5; // 矯正0int pos[MAXN << 1]; // 記錄0的位置int main(){ int t; //freopen("1.txt","r",stdin); scanf("%d",&t); for (int tt = 1; tt <= t; tt++){ printf("Case #%d:\n",tt); memset(pos,0,sizeof(pos)); int n; scanf("%d",&n); char str[10]; int dir = 1; // 方向標量 int ltop = ZERO; // 反向棧頂 int rtop = ZERO + 1; //正向棧頂 int lz = ZERO; // 反向棧頂0 int rz = ZERO + 1; // 正向棧頂0 int x; for (int i = 1;i <= n;i ++){ scanf("%s",str); if (str[0] == 'P' && str[1] == 'U'){ scanf("%d",&x); if (dir > 0){ if (x == 0) pos[rz++] = rtop; rtop++; }else { if (x == 0) pos[lz--] = ltop; ltop--; } }else if (str[0] == 'P' && str[1] == 'O'){ if (dir > 0){ if (pos[rz - 1] == rtop - 1) // 彈出0 pos[rz - 1] = 0,rz--; rtop--; }else { if (pos[lz + 1] == ltop + 1) // 彈出0 pos[lz + 1] = 0,lz++; ltop++; } }else if (str[0] == 'R'){ dir = - dir; }else{// cout << "top: " << ltop << " " << rtop << endl;// cout << "lz: " << lz << " " << rz << endl;// cout << "pos: " << pos[lz + 1] << " " << pos[rz - 1] << endl;// cout << "dir: " << dir << endl; if (ltop + 1 > rtop - 1){ // 棧中元素為空白 printf("Invalid.\n"); continue; } if (dir > 0){ if (pos[lz + 1] > ltop && pos[lz + 1] < rtop){ // 棧中有0 if (pos[lz + 1] == ltop + 1){ //棧底為0 puts("1"); continue; } // 考慮 111...110 與 1111...011...111 int l = pos[lz + 1] - ltop - 1; // 棧底0以下的1的個數 bool has = (pos[lz + 1] == rtop - 1 ? 0 : 1); // 0上是否有0 if ((l & 1) ^ has){ //分類討論得出 puts("1"); }else{ puts("0"); } }else { // 全1 int sum = rtop - 1 - ltop; if (sum & 1){ puts("1"); }else { puts("0"); } } }else { // 鏡像對稱,反向考慮即可 if (pos[rz - 1] > ltop && pos[rz - 1] < rtop){ if (pos[rz - 1] == rtop - 1){ puts("1"); continue; } int l = rtop - 1 - pos[rz - 1]; bool has = (pos[rz - 1] == ltop + 1 ? 0 : 1); if ((l & 1) ^ has){ puts("1"); }else{ puts("0"); } }else { int sum = rtop - 1 - ltop; if (sum & 1){ puts("1"); }else { puts("0"); } } } } } } return 0;}