CF1214E Petya and Construction Set(树上构造)
/* *author: zlc *zucc_acm_lab *just do it */ /* *cf1214e *题意: *给你2n个点,输入n个数,第i个数di表示i*2和i*2-1之间的距离为di *请你构造这棵树并输出 *构造树的一般方法是先造一条长链,然后在链上加分支 *先对长度数组从大到小排序 *构造出一条长度为n的链 *链的第i个位置放di所连的一个点 *如果i+di-1等于当前链的长度,就让链长度加1,把另一个点接上 *如果不是,就把另一点当成分支接在i+di-1个点后面 */ #include<bits/stdc++.h> using namespace std; typedef long long ll; const double pi=acos(-1.0); const double eps=1e-6; const int mod=1e9+7; const int inf=1e9; const int maxn=2e5+100; inline int read () {int x=0,f=1;char ch=getchar();while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;} ll qpow (ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} int n; int a[maxn]; vector<int> g[maxn]; struct qnode { int w,id; bool operator < (const qnode &r) const { return w>r.w; } }d[maxn]; int main () { n=read(); for (int i=1;i<=n;i++) { d[i].w=read(); d[i].id=i; } sort(d+1,d+n+1); int tot=n; for (int i=1;i<=n;i++) { a[i]=d[i].id*2-1; if (i+d[i].w-1>=tot) a[++tot]=d[i].id*2; else g[i+d[i].w-1].push_back(d[i].id*2); } for (int i=1;i<tot;i++) { printf("%d %d\n",a[i],a[i+1]); for (auto v:g[i]) printf("%d %d\n",a[i],v); } }