细 节 非 常 多 . . . . . . . . . 细节非常多......... 细节非常多.........

偶 数 全 用 1 操 作 去 乘 偶数全用1操作去乘 偶数全用1操作去乘

负 数 如 果 是 偶 数 也 都 这 么 乘 负数如果是偶数也都这么乘 负数如果是偶数也都这么乘

负 数 如 果 是 奇 数 就 先 用 1 操 作 直 到 最 大 的 负 数 负数如果是奇数就先用1操作直到最大的负数 负数如果是奇数就先用1操作直到最大的负数

然 后 最 大 的 负 数 应 该 和 0 去 操 作 1 抵 消 然后最大的负数应该和0去操作1抵消 然后最大的负数应该和0去操作1抵消

如 果 没 有 0 就 直 接 抹 掉 最 大 的 负 数 如果没有0就直接抹掉最大的负数 如果没有0就直接抹掉最大的负数

最 后 0 之 间 互 相 消 除 直 到 剩 下 一 个 0 , 操 作 2 抹 掉 最后0之间互相消除直到剩下一个0,操作2抹掉 最后0之间互相消除直到剩下一个0,操作2抹掉

(代码可能稍长,不过思路应该很明了)

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int n,a[maxn];
struct p{
int x,num;
bool operator < (const p&tmp ) const{
return x<tmp.x;
}
}fu[maxn],zh[maxn],zero[maxn];
int top1,top2,top3;
void print(p a,p b){
cout<<1<<" "<<a.num<<" "<<b.num<<endl;
}
int main()
{
ios::sync_with_stdio(false);
cin >> n;
for(int i=1;i<=n;i++)
{
cin >> a[i];
p temp={a[i],i};
if(a[i]==0) zero[++top3]=temp;
else if(a[i]>0) zh[++top2]=temp;
else fu[++top1]=temp;
}
sort(fu+1,fu+1+top1);
if(top1%2==1)//负数为奇数的情况
{
if(top3)//如果有0
{
cout<< 1 << " " << fu[top1].num << " " << zero[1].num<<endl;
for(int i=2;i<=top3;i++) print(zero[i-1],zero[i]);//抹掉一些0
if(top2==0&&top1==1) return 0;//如果已经只有这个0了,就不应该被抹去
cout<<2<<" "<<zero[top3].num<<endl;//抹掉最后一个0
for(int i=2;i<top1;i++) print(fu[i-1],fu[i]);
if(top1>1&&top2>=1) print(fu[top1-1],zh[1]);
for(int i=2;i<=top2;i++) print(zh[i-1],zh[i]);
}
else//没有0,那么抹除掉最大的负数即可
{
cout << 2 << " "<< fu[top1].num <<endl;
for(int i=2;i<top1;i++) print(fu[i-1],fu[i]);
if(top1>1&&top2>=1) print(fu[top1-1],zh[1]);
for(int i=2;i<=top2;i++) print(zh[i-1],zh[i]);
}
}
else
{
for(int i=2;i<=top3;i++) print(zero[i-1],zero[i]);//抹掉一些0
if(top1==0&&top2==0) return 0;//只有这个0了,不应该抹去
if(top3>=1)//有0才抹掉
cout<<2<<" "<<zero[top3].num<<endl;//抹掉最后一个0
for(int i=2;i<=top1;i++)
print(fu[i-1],fu[i]);
if(top1>=1&&top2>=1) print(fu[top1],zh[1]);
for(int i=2;i<=top2;i++)
print(zh[i-1],zh[i]);
}
}