这道题是noip题,你在哪个oj基本都能找到,这里就不给出题目大意了.
这道题我的思路就是输入之后,建一个栈来维护.
具体怎么维护,就是每次压入一个循环的时候,记录一下这次循环的各个信息.
我们维护信息只维护一个变量名,与一个省略过常数的时间复杂度.
省略过常数的时间复杂度只有三种情况:O(n),O(1)或O(0).
特别一说,若这一层为O(0),那么接下来的所有复杂度均为O(0).
然后我们只要遇到F入栈处理,遇到E就出栈.
那么每次入栈时,看前面一个的标记是什么(标记b为1是是O(n),为0是常数,为-1是O(0)),若是-1,这一层也是-1,否则跟上一层也没什么关系了.
所以代码大致如下:
#include<bits/stdc++.h> using namespace std; #define rep(i,j,k) for (int i=j;i<=k;i++) //专属神奇循环简写 struct stack{ char c; int b; }st[101]; bool b[101]; int top,T; int tt; bool flag=0; string ss; inline void start(){ rep(i,0,100) st[i].c=EOF,st[i].b=0,b[i]=0; top=0;flag=0; tt=0; top=0; } inline void push(){ int now=2; st[++top].c=ss[now]; rep(i,1,top-1) if (st[i].c==ss[now]) flag=1; if (st[top-1].b==-1){ st[top].b=-1; return; } int begin,end; now+=2; if (ss[now]=='n'){ if (ss[now+2]=='n') st[top].b=0; else st[top].b=-1; return; } begin=ss[now]-'0'; if (ss[now+1]<='9'&&ss[now+1]>='0') begin=begin*10+ss[now+1]-'0'; while (ss[now]!=' ') now++; now++; if (ss[now]=='n'){ st[top].b=1; b[++tt]=1; return; }else{ end=ss[now]-'0'; ss=ss+" "; if (ss[now+1]<='9'&&ss[now+1]>='0') end=end*10+ss[now+1]-'0'; if (end<begin) st[top].b=-1; else st[top].b=0; return; } } inline void pop(){ if (st[top].b==1) tt--; st[top].b=0; top--; } inline void one(){ getline(cin,ss); if (ss[0]=='F') push(); else pop(); } inline void work(){ int l,time; cin>>T; rep(i,1,T){ start(); b[0]=1; cin>>l; getline(cin,ss); if (ss[3]=='1') time=0; else { time=ss[5]-'0'; if (ss[6]<='9'&&ss[6]>='0') time=time*10+ss[6]-'0'; } flag=0; rep(i,1,l) one(); if (top||flag) { printf("ERR\n"); continue; } if (b[time]&&!b[time+1]) printf("Yes\n"); else printf("No\n"); } } inline void outo(){ } int main(){ //into(); work(); //outo(); return 0; }