有一棵n个点的无根树,每条边有一个正整数权值,表示长度,定义两点距离为在树上的最短路径的长度。
已知2到n-1每个点在树上与1和n的距离,请根据这些信息还原出这棵树。
(2<=n<=500000),1<=d<=1000000
解法:考虑1-n这条路径,如果上面没有其它点,说明都在一侧,特判。
否则上面至少有1个点,可以先求出1-n的距离=mini(d1,i+di,n)
再将所有在路径上的点找出,剩下的点只用1条边挂在这条链上。
#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define MAXN (1500000+10)
int n,a[MAXN],b[MAXN];
void case1() {
int p=abs(a[2]-b[2]);
if (!p) return;
Fork(i,3,n-1) if (abs(a[i]-b[i])!=p) return;
puts("TAK");
printf("%d %d %d\n",1,n,p);
Fork(i,2,n-1)
if (a[i]<b[i]) printf("1 %d %d\n",i,a[i]);
else printf("%d %d %d\n",n,i,b[i]);
exit(0);
}
int cmp(int i,int j) {
if (a[i]+b[i]!=a[j]+b[j]) return a[i]+b[i]<a[j]+b[j];
return a[i]<a[j];
}
int s[MAXN];
#define NIE {puts("NIE");exit(0);}
int v[MAXN]={};
int f[MAXN],g[MAXN];
int main()
{
// freopen("bzoj5100.in","r",stdin);
n=read();
Fork(i,2,n-1) a[i]=read();
Fork(i,2,n-1) b[i]=read();
if (n==2) {
puts("TAK\n1 2 1");exit(0);
}
case1();
For(i,n) s[i]=i;
sort(s+2,s+n,cmp);
int l=2,w=a[s[2]]+b[s[2]];
while(a[s[l+1]]+b[s[l+1]]==w&&l<n-1) ++l;
Fork(i,2,l-1) if (a[s[i]]==a[s[i+1]]) NIE
Fork(i,2,l) v[a[s[i]]]=s[i];
v[0]=1,v[w]=n;
Fork(i,l+1,n-1) {
int t=a[s[i]]+b[s[i]]-w;
if (t&1) NIE
t>>=1;
if (!t) NIE
if (!v[a[s[i]]-t]) NIE
f[i] = v[a[s[i]]-t];
g[i] = t;
}
puts("TAK");
printf("%d %d %d\n",1,s[2],a[s[2]]);
Fork(i,2,l-1)
printf("%d %d %d\n",s[i],s[i+1],a[s[i+1]]-a[s[i]]);
printf("%d %d %d\n",s[l],n,b[s[l]]);
Fork(i,l+1,n-1) {
printf("%d %d %d\n",s[i],f[i],g[i]);
}
return 0;
}