题目背景
某地ENLIGHTENED的XM研究所正在研究Portal的处理法则,想要揭示XM能量的来源以及应用XM能量。ENLIGHTENED的首席科学家Jacks发现其能量的运算法则以及运算方法,但是方法十分复杂,仅靠人手工计算是很难算出答案的,所以它需要你协助他完成计算。
题目描述
Portal计算XM能量是通过个22个栈(00号栈,11号栈)实现的,它把对XM能量的操作如下
PUSHPUSH XX NUMNUM
把NUMNUM加入到X号栈的栈顶。
POPPOP XX
把XX号栈的栈顶元素删除。
ADDADD XX
取出00号栈和11号栈的元素各一个,并且把它的和放入XX号栈。
SUBSUB XX
取出00号栈和11号栈的元素各一个,并且把它的差的绝对值放入XX号栈。
DELDEL XX
清空XX号栈中所有元素不管栈是否为空。
MOVEMOVE XX YY
循环操直到YY号栈为空,把YY号栈的栈顶元素加入到XX号栈,删除YY号栈的栈顶元素。
数据保证X和Y不相同
SWAPSWAP
将两个栈的所有元素调换。
ENDEND
代表命令结束,并且分两行分别输出0号栈和1号栈由栈顶到栈底的元素的值,若栈内无元素,输出NONE。数据保证指令以END结束且仅有一个END,并且也需要输出SUCCESS。
AKNOIAKNOI
等为无效操作,无效操作后不接数字。
更正不会有类似无效操作
对于每一行指令,若当前指令成功执行输出SUCCESS,若取出或删除元素时栈内为空或者没有对应指令输出UNSUCCESS并且不执行该行指令。
输入输出格式
输入格式:
输入若干行指令,以END指令结束
输出格式:
对于每一次操作,都要对应输出SUCCESS或者UNSUCCESS,对于END根据指令描述输出栈内元素。
输入输出样例
PUSH 0 10
PUSH 0 20
PUSH 0 30
PUSH 0 40
PUSH 1 50
PUSH 1 60
ADD 0
ADD 0
ADD 0
END
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
UNSUCCESS
SUCCESS
150 30 20 10
NONE
PUSH 0 10
PUSH 0 20
PUSH 0 30
PUSH 0 40
PUSH 1 50
PUSH 1 60
MOVE 0 1
END
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
SUCCESS
50 60 40 30 20 10
NONE
说明
对于20\%20%的数据 数据保证不会出现MOVE/SWAP操作,$命令总数 leq 100$
对于40\%40%的数据 $命令总数 leq 1000$
对于60\%60%的数据 数据保证MOVE/SWAP的操作次数不会超过1000010000次,$命令总数 leq 10^5$
对于100\%100%的数据 $0 leq X,Y leq 1,命令总数 leq 10^6$
数据保证无论任何情况,栈中元素的值XX满足$0 leq x leq 2^{63}-1$
/* 最暴力的模拟思路了 60分 正解应该是在move和swap操作上用了什么奇奇怪怪的高级的东西。 */ #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; string s; int x,y,top[3]; long long num[1000100],stack[3][1000100]; int main(){ while(cin>>s){ if(s[0]=='P'&&s[1]=='U'){ scanf("%d%d",&x,&y); stack[x][++top[x]]=y; printf("SUCCESS "); } else if(s[0]=='P'&&s[1]=='O'){ scanf("%d",&x); if(top[x]==0) printf("UNSUCCESS "); else{ top[x]--;printf("SUCCESS "); } } else if(s[0]=='A'){ scanf("%d",&x); if(top[1]==0||top[0]==0) printf("UNSUCCESS "); else{ int x0=stack[0][top[0]--]; int x1=stack[1][top[1]--]; stack[x][++top[x]]=x0+x1; printf("SUCCESS "); } } else if(s[0]=='S'&&s[1]=='U'){ scanf("%d",&x); if(top[1]==0||top[0]==0) printf("UNSUCCESS "); else{ int x0=stack[0][top[0]--]; int x1=stack[1][top[1]--]; stack[x][++top[x]]=abs(x0-x1); printf("SUCCESS "); } } else if(s[0]=='D'){ scanf("%d",&x);top[x]=0; printf("SUCCESS "); } else if(s[0]=='M'){ scanf("%d%d",&x,&y); while(top[y]){ int tmp=stack[y][top[y]]; stack[x][++top[x]]=tmp; top[y]--; } printf("SUCCESS "); } else if(s[0]=='S'&&s[1]=='W'){ for(int i=1;i<=top[0];i++) num[i]=stack[0][i]; for(int i=1;i<=top[1];i++) stack[0][i]=stack[1][i]; for(int i=1;i<=top[0];i++) stack[1][i]=num[i]; swap(top[0],top[1]); printf("SUCCESS "); } else if(s[0]=='E'){ printf("SUCCESS "); if(top[0]) for(int i=top[0];i>=1;i--) cout<<stack[0][i]<<" "; else printf("NONE");printf(" "); if(top[1]) for(int i=top[1];i>=1;i--) cout<<stack[1][i]<<" "; else printf("NONE"); return 0; } } }

所以说emm...正解是用链表进行维护的。
#include <bits/stdc++.h> #define ll long long #define rep(i,l,r) for (int i = l; i <= r; i++) #define getc(x) getchar(x) #define putc(x) putchar(x) template <typename T> inline void read(T &x) { x = 0; register char ch; register bool fl = 0; while (ch = getc(), ch < 48 || 57 < ch) fl ^= ch == '-'; x = (ch & 15); while (ch = getc(), 47 < ch && ch < 58) x = (x << 1) + (x << 3) + (ch & 15); if (fl) x = -x; } template <typename T> inline void readc(T &x) { while (x = getc(), !islower(x) && !isupper(x)); } template <typename T> inline void print(T x, char c = ' ') { static int buf[40]; if (x == 0) { putc('0'); putc(c); return; } if (x < 0) putc('-'), x = -x; for (buf[0] = 0; x; x /= 10) buf[++buf[0]] = x % 10 + 48; while (buf[0]) putc((char) buf[buf[0]--]); putc(c); } const int maxn = 6000010; int x, y, opt, cnt, finish_game; int pre[maxn], nxt[maxn], hed[2]; ll k, val[maxn]; inline void link(int u, int v) { nxt[u] = v; pre[v] = u; } inline void simple_push(int u, int v, ll w) { val[++cnt] = w; link(u, cnt); link(cnt, v); } inline void push(int x, ll k) { if (x == 0) simple_push(pre[2], 2, k); else simple_push(2, nxt[2], k); } inline ll pop(int u) { link(pre[u], nxt[u]); return val[u]; } void printout(int u) { if (u == 0) { if (pre[2] == 0) { printf("NONE "); return; } for (int i = pre[2]; i != 0; i = pre[i]) print(val[i]); putc(' '); } else { if (nxt[2] == 1) { printf("NONE "); return; } for (int i = nxt[2]; i != 1; i = nxt[i]) print(val[i]); putc(' '); } } int read_opt() { char c1, c2; readc(c1), readc(c2); if (c1 == 'P') return c2 == 'U' ? 1 : 2; if (c1 == 'A') return 3; if (c1 == 'S') { if (c2 == 'U') return 4; readc(c2), readc(c2); return 7; } if (c1 == 'D') return 5; if (c1 == 'M') return 6; if (c1 == 'E') return 8; return 0; } bool solve(int opt) { if (opt == 1) { read(x), read(k); x = hed[x]; push(x, k); } else if (opt == 2) { read(x); x = hed[x]; if (x == 0) { if (pre[2] == 0) return false; pop(pre[2]); } else { if (nxt[2] == 1) return false; pop(nxt[2]); } } else if (opt == 3) { read(x); x = hed[x]; if (pre[2] == 0 || nxt[2] == 1) return false; push(x, pop(pre[2]) + pop(nxt[2])); } else if (opt == 4) { read(x); x = hed[x]; if (pre[2] == 0 || nxt[2] == 1) return false; push(x, std::abs(pop(pre[2]) - pop(nxt[2]))); } else if (opt == 5) { read(x); x = hed[x]; if (x == 0) link(0, 2); else link(2, 1); } else if (opt == 6) { read(x), read(y); x = hed[x], y = hed[y]; link(pre[2], nxt[2]); if (x == 0) { link(pre[1], 2); link(2, 1); } else { link(2, nxt[0]); link(0, 2); } } else if (opt == 7) { std::swap(hed[0], hed[1]); } else if (opt == 8) { finish_game = 1; } return true; } int main() { cnt = 2; link(0, 2), link(2, 1); hed[0] = 0, hed[1] = 1; while (!finish_game) { opt = read_opt(); if (solve(opt)) puts("SUCCESS"); else puts("UNSUCCESS"); } printout(!hed[0] ? 0 : 1); printout(!hed[0] ? 1 : 0); return 0; }