Codeforces Round #510 (Div. 2) --C. Array Product(分类讨论)

                                      C. Array Product

                                                                      time limit per test:1 second

                                                             memory limit per test:256 megabytes

                                                                           input:standard input

                                                                          output:standard output

You are given an array aa consisting of nn integers. You can perform the following operations with it:

  1. Choose some positions ii and jj (1≤i,j≤n,i≠j1≤i,j≤n,i≠j ), write the value of ai⋅ajai⋅aj into the jj -th cell and remove the number from the ii -th cell;
  2. Choose some position ii and remove the number from the ii -th cell (this operation can be performed no more than once and at any point of time, not necessarily in the beginning).

The number of elements decreases by one after each operation. However, the indexing of positions stays the same. Deleted numbers can't be used in the later operations.

Your task is to perform exactly n−1n−1 operations with the array in such a way that the only number that remains in the array is maximum possible. This number can be rather large, so instead of printing it you need to print any sequence of operations which leads to this maximum number. Read the output format to understand what exactly you need to print.

Input

The first line contains a single integer nn (2≤n≤2⋅1052≤n≤2⋅105 ) — the number of elements in the array.

The second line contains nn integers a1,a2,…,ana1,a2,…,an (−109≤ai≤109−109≤ai≤109 ) — the elements of the array.

Output

Print n−1n−1 lines. The kk -th line should contain one of the two possible operations.

The operation of the first type should look like this: 1 ik jk1 ik jk , where 11 is the type of operation, ikik and jkjk are the positions of the chosen elements.

The operation of the second type should look like this: 2 ik2 ik , where 22 is the type of operation, ikik is the position of the chosen element. Note that there should be no more than one such operation.

If there are multiple possible sequences of operations leading to the maximum number — print any of them.

Examples

Input

5
5 -2 0 1 -3

Output

2 3
1 1 2
1 2 4
1 4 5

Input

5
5 2 0 4 0

Output

1 3 5
2 5
1 1 2
1 2 4

Input

2
2 -1

Output

2 2

Input

4
0 -10 0 0

Output

1 1 2
1 2 3
1 3 4

Input

4
0 0 0 0

Output

1 1 2
1 2 3
1 3 4

Note

Let X be the removed number in the array. Let's take a look at all the examples:

The first example has, for example, the following sequence of transformations of the array: [5,−2,0,1,−3]→[5,−2,X,1,−3]→[X,−10,X,1,−3]→[5,−2,0,1,−3]→[5,−2,X,1,−3]→[X,−10,X,1,−3]→ [X,X,X,−10,−3]→[X,X,X,X,30][X,X,X,−10,−3]→[X,X,X,X,30] . Thus, the maximum answer is 3030 . Note, that other sequences that lead to the answer 3030 are also correct.

The second example has, for example, the following sequence of transformations of the array: [5,2,0,4,0]→[5,2,X,4,0]→[5,2,X,4,X]→[X,10,X,4,X]→[5,2,0,4,0]→[5,2,X,4,0]→[5,2,X,4,X]→[X,10,X,4,X]→ [X,X,X,40,X][X,X,X,40,X] . The following answer is also allowed:

1 5 3
1 4 2
1 2 1
2 3

Then the sequence of transformations of the array will look like this: [5,2,0,4,0]→[5,2,0,4,X]→[5,8,0,X,X]→[40,X,0,X,X]→[5,2,0,4,0]→[5,2,0,4,X]→[5,8,0,X,X]→[40,X,0,X,X]→ [40,X,X,X,X][40,X,X,X,X] .

The third example can have the following sequence of transformations of the array: [2,−1]→[2,X][2,−1]→[2,X] .

The fourth example can have the following sequence of transformations of the array: [0,−10,0,0]→[X,0,0,0]→[X,X,0,0]→[X,X,X,0][0,−10,0,0]→[X,0,0,0]→[X,X,0,0]→[X,X,X,0] .

The fifth example can have the following sequence of transformations of the array: [0,0,0,0]→[X,0,0,0]→[X,X,0,0]→[X,X,X,0][0,0,0,0]→[X,0,0,0]→[X,X,0,0]→[X,X,X,0] .

 

题意就是给定两种操作:第一种是选两个数组下标i,j;使a[j]=a[i]*a[j],并且标记a[i]使其不能参加后来的操作。第二种操作表示标记a[i]使其不能参加后来的操作(限一次),则n-1次操作后,仅剩一个数k未被标记,求使得k最大的步骤。

解法:分类讨论:设小于0的元素个数为cnt1,等于0为cnt2,大于0为cnt3;

(1):cnt1=cnt2=0,cnt3!=0:进行n-1次操作1;

(2):cnt2=cnt3=0,cnt1!=0:若cnt1为奇数,则先去掉最大的负数(即操作2),然后对剩下的n-1个数进行n-2次操作1;

(3):cnt1=cnt3=0,cnt2!=0;进行n-1次操作1;

(4):cnt1=0,cnt2!=0,cnt3!=0:则先对cnt2个0进行cnt2-1次操作1,然后去掉那个0,剩下的cnt3个数进行cnt3-1次操作1;

(5):cnt2=0,cnt1!=0,cnt3!=0:若cnt1为奇数,去掉最大的,然后剩下的进行操作1,否则,全部进行操作1;

(6):cnt3=0,cnt1!=0,cnt2!=0:若cnt1为奇数,把最大的负数同剩余的0进行操作一,删去最终的数,再把剩下的负数进行操作1;

否则,把cnt2个0进行cnt2-1个操作1,删去最后的0,再把cnt1个负数进行cnt1-1个操作1;

(7):cnt1!=0,cnt2!=0,cnt3!=0:先把cnt3个正数进行cnt3-1个操作1,然后若cnt1为奇数,把最大的负数同cnt2个0进行cnt2个操作1,去掉结果,然后把剩下的cnt1-1个负数进行cnt2-2个操作1;否则对cnt2个0进行cnt2-1个操作1,删去结果,再对cnt1个负数进行操作1;最后把两个结果进行操作一

赛时写的垃圾AC代码:

#include<iostream>
#include<cstdio>
#include<vector>
#include<bitset>
#include<stack>
#include<set>
#include<queue>
#include<map>
#include<cmath>
#include<string>
#include<cstring>
#include<ctime>
#include<fstream>
#include<cstdlib>
#include<algorithm>

using namespace std;

#define pii pair<int, int>
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define per(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a,b) for(int i=a;i>=b;i--)
#define all(x) x.begin(),x.end()
#define PER(i,x) for(auto i=x.begin();i!=x.end();i++)
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
typedef long long ll;
const double eps=1.0e-5;
const int maxn=200000+10;

int n,b[maxn],c[maxn],d[maxn];

struct node{
	int x,y;
}a[maxn];

bool cmp1(node a,node b)
{
	return a.x<b.x;
}

bool cmp2(node a,node b)
{
	return a.y<b.y;
}

int main()
{
	//freopen("C:\\Users\\MAC\\Desktop\\in.txt","r",stdin);
	scanf("%d",&n);
	
	int flag,minn=-inf;
	int cnt1=0,cnt2=0,cnt3=0;
	per(i,1,n){
		scanf("%d",&a[i].x);
		a[i].y=i;
		if(a[i].x<0){
			cnt1++,b[cnt1]=i;
			if(a[i].x>minn){
				flag=i;
				minn=a[i].x;
			}
		}
		else if(a[i].x==0) cnt2++,c[cnt2]=i;
		else cnt3++,d[cnt3]=i;
	}
	
	sort(a+1,a+1+n,cmp1);
	if(cnt1==0&&cnt2==0){
		per(i,1,n-1) printf("1 %d %d\n",i,i+1);
	}else if(cnt2==0&&cnt3==0){
		if(n%2){
			printf("2 %d\n",a[n].y);
			per(i,1,n-2){
				printf("1 %d %d\n",a[i].y,a[i+1].y);
			}
		}else{
			per(i,1,n-1) printf("1 %d %d\n",i,i+1);
		}
	}else if(cnt1==0&&cnt3==0){
		per(i,1,n-1) printf("1 %d %d\n",i,i+1);
	}else if(cnt1==0){
		per(i,1,cnt2-1) printf("1 %d %d\n",c[i],c[i+1]);
		printf("2 %d\n",c[cnt2]);
		per(i,1,cnt3-1) printf("1 %d %d\n",d[i],d[i+1]);
	}else if(cnt2==0){
		if(cnt1%2){
			printf("2 %d\n",flag);
			per(i,1,cnt1-1){
				if(b[i]==flag) continue;
				else if(b[i+1]==flag) b[i+1]=b[i];
				else printf("1 %d %d\n",b[i],b[i+1]);
			}
			if(cnt1>1) printf("1 %d %d\n",b[cnt1],d[1]);
			per(i,1,cnt3-1) printf("1 %d %d\n",d[i],d[i+1]);
		}
		else{
			per(i,1,cnt1-1) printf("1 %d %d\n",b[i],b[i+1]);
			printf("1 %d %d\n",b[cnt1],d[1]);
			per(i,1,cnt3-1) printf("1 %d %d\n",d[i],d[i+1]);
		}
	}else if(cnt3==0){
		if(cnt1%2){
			printf("1 %d %d\n",flag,c[1]);
			per(i,1,cnt2-1) printf("1 %d %d\n",c[i],c[i+1]);
			if(cnt1>1) printf("2 %d\n",c[cnt2]);
			per(i,1,cnt1-1){
				if(b[i]==flag) continue;
				else if(b[i+1]==flag) b[i+1]=b[i];
				else printf("1 %d %d\n",b[i],b[i+1]);
			}
		}
		else{
		    per(i,1,cnt2-1) printf("1 %d %d\n",c[i],c[i+1]);
			per(i,1,cnt1-1) printf("1 %d %d\n",b[i],b[i+1]);
			printf("2 %d\n",c[cnt2]);
		}
	}else{
		if(cnt1%2){
			printf("1 %d %d\n",flag,c[1]);
			per(i,1,cnt2-1) printf("1 %d %d\n",c[i],c[i+1]);
			printf("2 %d\n",c[cnt2]);
			per(i,1,cnt1-1){
				if(b[i]==flag){
					continue;
				}else if(b[i+1]==flag){
					b[i+1]=b[i];
				}else printf("1 %d %d\n",b[i],b[i+1]);
			}
			if(cnt1>1) printf("1 %d %d\n",b[cnt1],d[1]);
			per(i,1,cnt3-1) printf("1 %d %d\n",d[i],d[i+1]);
		}
		else{
		    per(i,1,cnt2-1) printf("1 %d %d\n",c[i],c[i+1]);
			per(i,1,cnt1-1) printf("1 %d %d\n",b[i],b[i+1]);
			printf("2 %d\n",c[cnt2]);
			printf("1 %d %d\n",b[cnt1],d[1]);
			per(i,1,cnt3-1) printf("1 %d %d\n",d[i],d[i+1]);
		}
	}
	
	
}

赛后重写了一下:

#include<iostream>
#include<cstdio>
#include<vector>
#include<bitset>
#include<stack>
#include<set>
#include<queue>
#include<map>
#include<cmath>
#include<string>
#include<cstring>
#include<ctime>
#include<fstream>
#include<cstdlib>
#include<algorithm>

using namespace std;

#define pii pair<int, int>
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define per(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a,b) for(int i=a;i>=b;i--)
#define all(x) x.begin(),x.end()
#define PER(i,x) for(auto i=x.begin();i!=x.end();i++)
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
typedef long long ll;
const double eps=1.0e-5;
const int maxn=200000+10;

int cnt1=0,cnt2=0,cnt3=0,n,tmp,ma=-inf,flag,a[maxn],b[maxn],c[maxn];

int main()
{
	//freopen("C:\\Users\\MAC\\Desktop\\in.txt","r",stdin);
	scanf("%d",&n);
	per(i,1,n){
		scanf("%d",&tmp);
		if(tmp<0){
			cnt1++;a[cnt1]=i;
			if(tmp>ma){ma=tmp;flag=i;}
		}
		else if(tmp==0) cnt2++,b[cnt2]=i;
		else cnt3++,c[cnt3]=i;
	}
	
	per(i,1,cnt3-1) printf("1 %d %d\n",c[i],c[i+1]);
	if(cnt1){
		if(cnt1%2){
			per(i,1,cnt1-1){
				if(a[i]==flag) continue;
				if(a[i+1]==flag) a[i+1]=a[i];
				else printf("1 %d %d\n",a[i],a[i+1]);
			}
			per(i,1,cnt2) printf("1 %d %d\n",flag,b[i]),flag=b[i];
			if(cnt3||cnt1>1)printf("2 %d\n",cnt2?b[cnt2]:flag);
			if(cnt3&&cnt1>1) printf("1 %d %d\n",a[cnt1],c[cnt3]);
		}else{
			per(i,1,cnt2-1) printf("1 %d %d\n",b[i],b[i+1]);
			per(i,1,cnt1-1) printf("1 %d %d\n",a[i],a[i+1]);
			if(cnt2) printf("2 %d\n",b[cnt2]);
			if(cnt3) printf("1 %d %d\n",a[cnt1],c[cnt3]);
		}
	}else{
		per(i,1,cnt2-1) printf("1 %d %d\n",b[i],b[i+1]);
		if(cnt2&&cnt3) printf("2 %d\n",b[cnt2]);
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值