題意:對0,1序列進行四種操作:壓進棧,彈出棧,轉置,查詢所有數的nand;
思路:首先我們發現暴力會超時,壓棧好寫,彈出也好寫,但是查詢怎麼搞,轉置怎麼搞,後來可以發現,從棧的底部往上第一個0的位置以上如果還有元素,那麼該位置的nand結果就是1,如果沒有就是0,那麼我們只需要知道距離棧低最近的0的位置就好,至於轉置,我們可以用deque可以在前端插入值這個良好的性質,沒有轉置時候我們從前往後操作,轉置後從後往前操作,我們把所有的0的位置裝進這個雙向隊列,查詢時只要知道首次被壓進棧的值是多少就可得出答案。
代碼:
#include<bits/stdc++.h>
#include<deque>
#define maxn 500000
using namespace std;
deque <int> dq;
int s[maxn];
int main()
{
int T,n,k=1,f,fa,a,l,r;
char op[10];
cin>>T;
while(T--){
scanf("%d",&n);
memset(s,-1,sizeof(s));
printf("Case #%d:\n",k++);
r=250001;
l=r-1;
fa=0;
f=1;
dq.clear();
while(n--){
scanf("%s",op);
if(op[0]=='P'&&op[1]=='U'){
scanf("%d",&a);
if(f){
if(!a) dq.push_back(r);
s[r]=a;
r++;
}
else{
if(!a) dq.push_front(l);
s[l]=a;
l--;
}
fa++;
}
else if(op[0]=='P'&&op[1]=='O'){
if(!fa) continue;
if(f){
if(s[r-1]==0)
dq.pop_back();
r--;
}
else{
if(s[l+1]==0)
dq.pop_front();
l++;
}
fa--;
}
else if(op[0]=='Q'){
int ans;
if(fa==0)
cout<<"Invalid."<<endl;
else if(fa==1) cout<<s[l+1]<<endl;
else{
if(f){
if(dq.empty()) ans=fa;
else ans=dq.front()==r-1?fa-1:dq.front()-l;
}
else{
if(dq.empty()) ans=fa;
else ans=dq.back()==l+1?fa-1:r-dq.back();
}
if(ans%2==0) cout<<0<<endl;
else cout<<1<<endl;
}
}
else f=f^1;
}
}
}