Codeforces Round #583 --E. Petya and Construction Set--树上构造

E. Petya and Construction Set

time limit per test

1 second

memory limit per test

512 megabytes

input

standard input

output

standard output

It's Petya's birthday party and his friends have presented him a brand new "Electrician-nn" construction set, which they are sure he will enjoy as he always does with weird puzzles they give him.

Construction set "Electrician-nn" consists of 2n−12n−1 wires and 2n2n light bulbs. Each bulb has its own unique index that is an integer from 11to 2n2n, while all wires look the same and are indistinguishable. In order to complete this construction set one has to use each of the wires to connect two distinct bulbs. We define a chain in a completed construction set as a sequence of distinct bulbs of length at least two, such that every two consecutive bulbs in this sequence are directly connected by a wire. Completed construction set configuration is said to be correct if a resulting network of bulbs and wires has a tree structure, i.e. any two distinct bulbs are the endpoints of some chain.

Petya was assembling different configurations for several days, and he noticed that sometimes some of the bulbs turn on. After a series of experiments he came up with a conclusion that bulbs indexed 2i2i and 2i−12i−1 turn on if the chain connecting them consists of exactly didiwires. Moreover, the following important condition holds: the value of didi is never greater than nn.

Petya did his best but was not able to find a configuration that makes all bulbs to turn on, so he seeks your assistance. Please, find out a configuration that makes all bulbs shine. It is guaranteed that such configuration always exists.

Input

The first line of the input contains a single integer nn (1≤n≤1000001≤n≤100000) — the parameter of a construction set that defines the number of bulbs and the number of wires.

Next line contains nn integers d1,d2,…,dnd1,d2,…,dn (1≤di≤n1≤di≤n), where didi stands for the number of wires the chain between bulbs 2i2i and 2i−12i−1 should consist of.

Output

Print 2n−12n−1 lines. The ii-th of them should contain two distinct integers aiai and bibi (1≤ai,bi≤2n1≤ai,bi≤2n, ai≠biai≠bi) — indices of bulbs connected by a wire.

If there are several possible valid answer you can print any of them.

Examples

input

Copy

3
2 2 2

output

Copy

1 6
2 6
3 5
3 6
4 5

input

Copy

4
2 2 2 1

output

Copy

1 6
1 7
2 6
3 5
3 6
4 5
7 8

input

Copy

6
2 2 2 2 2 2

output

Copy

1 3
2 3
3 5
4 5
5 7
6 7
7 12
8 12
9 11
9 12
10 11

input

Copy

2
1 1

output

Copy

1 2
1 4
3 4

Note

Answer for the first sample test.

Answer for the second sample test.

 

对应i和2i,他们之间的距离为di,构造这个树。保证有解。

学到的一种思路就是先构造奇数链,把1 3 5...先放到链上,对于一个样例来说:

然后对他们的di从大到小排序,先考虑di大的。

第一种情况:对与i=1来说i+d1<=r,所以我们可以把它放到和3相连的分支上。

利用vector的特性,v[x][0]是3,v[x][1]是2......

第二种情况:对于i=2来说,i+d2>=r(3),此时把它放到链的末尾符合题意!于是v[4][0]就是4啦。

不断这样构造就可以啦。

最后输出的时候,注意1的情况特殊输出一下,其他先输出前面的和他,然后输出它和他的分支节点。

#include <algorithm>    //STL通用算法
#include <bitset>     //STL位集容器
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>      //STL双端队列容器
#include <exception>    //异常处理类
#include <fstream>
#include <functional>   //STL定义运算函数(代替运算符)
#include <limits>
#include <list>      //STL线性列表容器
#include <map>       //STL 映射容器
#include <iomanip>
#include <ios>      //基本输入/输出支持
#include<iosfwd>     //输入/输出系统使用的前置声明
#include <iostream>
#include <istream>     //基本输入流
#include <ostream>     //基本输出流
#include <queue>      //STL队列容器
#include <set>       //STL 集合容器
#include <sstream>    //基于字符串的流
#include <stack>      //STL堆栈容器    
#include <string>     //字符串类
#include <vector>     //STL动态数组容器
#define ll long long
using namespace std;
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define dep(i,a,b) for(register int i=(a);i>=(b);i--)
//priority_queue<int,vector<int>,less<int> >q;
int dx[]= {-1,1,0,0,-1,-1,1,1};
int dy[]= {0,0,-1,1,-1,1,1,-1};
const int maxn = 1000000+66;
const int maxm=100000+66;
const ll mod=1e9+7;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
const int INF=99999999;
struct node
{
    int lid;//奇数点编号
    int len;//题目中长度
} arr[maxn];
bool cmp(node a,node b)
{
    return a.len>b.len;
}
vector<vector<node> >v(maxn);
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        rep(i,1,n)
        {
            v[i].clear();
            scanf("%d",&arr[i].len);
            arr[i].lid=2*i-1;
        }
        sort(arr+1,arr+n+1,cmp);
        rep(i,1,n)
        {
            v[i].push_back(arr[i]);
            // cout<<"--";
        }
        //构造一个1 3 5 7的链
        int r=n;
        rep(i,1,n)
        {
            node tmp=v[i][0];//取第一个
            int len=tmp.len;
            int lid=tmp.lid;
            if(i+len<=r)
            {
                v[i+len-1].push_back(node{lid+1,1});
            }
            else
            {
                v[++r].push_back(node{lid+1,1});
            }
        }
        rep(i,1,r)
        {
            if(i!=1)
                printf("%d %d\n",v[i-1][0].lid,v[i][0].lid);
            int s=v[i].size();
            for(int j=1; j<s; ++j)
                printf("%d %d\n",v[i][0].lid,v[i][j].lid);
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值