民间数据 50pts,官方数据 55pts,洛谷民间数据最后 10 个点和官方数据 #11~19 RE,但是发给 Mrkn_chenyx12 能过官方数据 #19。
讨论区各种 Hack 对于我的代码全部无效,只有 n≥3 的大数据才能够卡掉。
经过分析发现是试图将元素放入空栈时发现没有空栈,然而我检测了代码逻辑发现我在每次操作后都保证了空栈的存在。
求救,代码如下,加了注释:
#include<bits/stdc++.h>
using namespace std;
deque<int> stk[305];
int t, n, m, k, pos, nxt, a[2000005], buk[2005], ins[2005];
set<int> siz[20];
struct operator_{
int op, u, v;
};
queue<operator_> operator__;
void gensiz(int u, int lsz){//更新一个栈的大小
if (siz[lsz].find(u) == siz[lsz].end())
exit(3256);
siz[lsz].erase(u);
siz[stk[u].size()].insert(u);
}
void print(int u){
cerr << u << "(" << stk[u].size() << "):";
if (stk[u].empty()){
cout << "\n";
return;
}
cerr << stk[u].front() << " " << stk[u].back() << "\n";
}
void printall(){
for (int i = 1; i <= n; i++)
print(i);
}
void stk_ins(int u, int x){//插入元素
int lu = stk[u].size();
// cerr << "1 " << u << "\n";
operator__.push({1, u, 0});
stk[u].push_back(x);
ins[x] = u;
gensiz(u, lu);
}
void c_bottom(int u, int v){//底部消除
// cerr << "2 " << u << " " << v << "\n";
operator__.push({2, u, v});
if (stk[u].empty() || stk[v].empty())
exit(325609);
if (stk[u].front() != stk[v].front())
exit(3256090);
int lu = stk[u].size(), lv = stk[v].size();
ins[stk[u].front()] = -1;
stk[u].pop_front();
stk[v].pop_front();
gensiz(u, lu);
gensiz(v, lv);
}
void c_top(int u, bool op = 1){//顶部连续两张牌相同
if (stk[u].size() < 2)
exit(32560900);
int lu = stk[u].size();
int x = stk[u].back();
if (op)
ins[x] = -1;
stk[u].pop_back();
int y = stk[u].back();
stk[u].pop_back();
if (x != y)
exit(325609000);
gensiz(u, lu);
}
void op1_1(int x){//策略 1-1:至少两个栈为空的情况
if (ins[x] == -1){//该元素未入栈,直接放入空栈
int ppos = *siz[0].begin();
stk_ins(ppos, x);
}else{
if (stk[ins[x]].back() == x){//在顶部,放到顶部然后弹出
stk_ins(ins[x], x);
c_top(ins[x]);
}else if (stk[ins[x]].front() == x){//在底部,放入空栈底部然后消去
int tins = ins[x];
int ppos = *siz[0].begin();
stk_ins(ppos, x);
c_bottom(ppos, tins);
}
}
}
void op1_2(int x){//策略 1-2:只有一个栈为空,且至少有一个栈元素个数为 1
// cerr << x << "\n";
if (ins[x] == -1){//该元素未入栈,放入元素个数为 1 的栈
int ppos = *siz[1].begin();
stk_ins(ppos, x);
}else{
if (stk[ins[x]].back() == x){//在顶部,放到栈顶弹出
stk_ins(ins[x], x);
c_top(ins[x]);
}else if (stk[ins[x]].front() == x){//在底部,放到空栈栈底消去
int tins = ins[x];
int ppos = *siz[0].begin();
stk_ins(ppos, x);
c_bottom(ppos, tins);
}
}
}
int op2(int pos, int x){
if (ins[x] == -1){
if (a[pos + 1] == x){//连续两张相同,直接消掉
int ppos = *siz[0].begin();
stk_ins(ppos, x);
stk_ins(ppos, x);
c_top(ppos);
return pos + 1;
}else{
int op = 0, id = 0;
for (int i = pos + 1; i <= m; i++){
if (a[i] == x){//目标与当前元素相同
id = i;
op = 1;
break;
}else if (stk[ins[a[i]]].front() == a[i]){//目标是栈底元素
id = i;
op = 2;
break;
}
}
if (op == 1){//目标与当前元素相同
int ppos = *siz[0].begin();
stk_ins(ppos, x);
for (int i = pos + 1; i <= id; i++){
if (ins[a[i]] == -1){//当前元素没出现过,放到空闲的栈
if (siz[1].size()){
int targ = *siz[1].begin();
if (targ == ppos)
targ = *(++siz[1].begin());
stk_ins(targ, a[i]);
}
continue;
}
if (stk[ins[a[i]]].back() == a[i]){//消掉
stk_ins(ins[a[i]], a[i]);
c_top(ins[a[i]]);
}
}
return id;
}else{
int cnt = 0;
for (int i = pos + 1; i < id; i++){//统计对应栈顶元素个数
if (a[i] == stk[ins[a[id]]].back())
cnt++;
}
if (cnt & 1){//如果为奇数,新元素放空栈,最后从上面消栈底元素
int ppos = *siz[0].begin();
stk_ins(ppos, x);
for (int i = pos + 1; i <= id; i++){
if (ins[a[i]] == -1){
if (siz[1].size()){
int targ = *siz[1].begin();
if (targ == ppos)
targ = *(++siz[1].begin());
stk_ins(targ, a[i]);
}else if (siz[0].size()){
int targ = *siz[0].begin();
stk_ins(targ, a[i]);
}
continue;
}
if (stk[ins[a[i]]].back() == a[i]){
stk_ins(ins[a[i]], a[i]);
c_top(ins[a[i]]);
}
}
return id;
}else{//如果为偶数,新元素放栈顶,最后从底部消
int ppos = ins[a[id]];
int ntop = stk[ins[a[id]]].back();
stk_ins(ppos, x);
for (int i = pos + 1; i < id; i++){
if (a[i] == ntop){
if (stk[ppos].back() == ntop){
stk_ins(ins[a[i]], a[i]);
c_top(ins[a[i]], 0);
}else
stk_ins(ppos, a[i]);
continue;
}
if (ins[a[i]] == -1){
if (siz[1].size()){
int targ = *siz[1].begin();
stk_ins(targ, a[i]);
}
}else{
stk_ins(ins[a[i]], a[i]);
c_top(ins[a[i]]);
}
}
int ppos2 = *siz[0].begin(), tins = ins[a[id]];
stk_ins(ppos2, a[id]);
c_bottom(tins, ppos2);
return id;
}
}
}
}else{
if (stk[ins[x]].back() == x){//消除顶部
stk_ins(ins[x], x);
c_top(ins[x]);
}else{//消除底部
int tins = ins[x];
int ppos = *siz[0].begin();
stk_ins(ppos, x);
c_bottom(ppos, tins);
}
return pos;
}
}
int work(int pos){
if (siz[0].size() > 1)//两个空栈
op1_1(a[pos]);
else if (siz[0].size() == 1 && siz[1].size())//一个空栈和一个只有一个元素的栈
op1_2(a[pos]);
else//一个空栈
return op2(pos, a[pos]);
return 0;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> t;
while (t--){
cin >> n >> m >> k;
for (int i = 1; i <= k; i++)//初始化
buk[a[i]] = 0;
for (int i = 0; i <= 15; i++)
siz[i].clear();
for (int i = 1; i <= n; i++){
while (!stk[i].empty())
stk[i].pop_front();
siz[0].insert(i);
}
for (int i = 1; i <= m; i++){
cin >> a[i];
buk[a[i]]++;
ins[a[i]] = -1;
}
for (int i = 1; i <= m; i++){//进行操作
int res = work(i);
if (res)
i = res;
// cerr << i << "\n";
// printall();
// cerr << "\n";
// for (int j = 1; j <= n; j++){
// cout << j << ":";
// cout << stk[j].size() << " ";
// if (stk[j].size() == 1)
// cout << stk[j].front();
// else if (stk[j].size() == 2)
// cout << stk[j].front() << " " << stk[j].back();
// cout << "\n";
// }
}
cout << operator__.size() << "\n";//输出解
while (!operator__.empty()){
operator_ tmp = operator__.front();
operator__.pop();
if (tmp.op == 1)
cout << 1 << " " << tmp.u << "\n";
else
cout << 2 << " " << tmp.u << " " << tmp.v << "\n";
}
}
return 0;
}