[atARC103F]Distance Sums
给定$n$个数$d_{i}$,构造一棵$n$个点的树使得$\forall 1\le i\le n,\sum_{j=1}^{n}dist(i,j)=d_{i}$
其中$dist(i,j)$表示$i$到$j$的路径上所经过的边数,若无解输出-1
$2\le n\le 10^{5}$,$1\le d_{i}\le 10^{12}$,保证$d_{i}$各不相同
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100005 4 #define pli pair<long long,int> 5 #define fi first 6 #define se second 7 vector<pli>e; 8 int n,sz[N]; 9 pli d[N]; 10 int main(){ 11 scanf("%d",&n); 12 for(int i=1;i<=n;i++){ 13 scanf("%lld",&d[i].fi); 14 d[i].se=i; 15 } 16 sort(d+1,d+n+1); 17 for(int i=1;i<=n;i++)sz[i]=1; 18 for(int i=n;i>1;i--){ 19 int fa=lower_bound(d+1,d+i+1,make_pair(d[i].fi+(2*sz[i]-n),0))-d; 20 if (d[fa].fi!=d[i].fi+(2*sz[i]-n)){ 21 printf("-1"); 22 return 0; 23 } 24 sz[fa]+=sz[i]; 25 e.push_back(make_pair(d[fa].se,d[i].se)); 26 } 27 for(int i=2;i<=n;i++)d[1].fi-=sz[i]; 28 if (d[1].fi)printf("-1"); 29 else 30 for(int i=0;i<n-1;i++)printf("%d %d\n",e[i].fi,e[i].se); 31 }