1. 程式人生 > >BZOJ5100 POI2018Plan metra(構造)

BZOJ5100 POI2018Plan metra(構造)

  容易發現要麼1和n直接相連,要麼兩點距離即為所有dx,1+dx,n的最小值。若為前者,需要滿足所有|d1-dn|都相等,掛兩棵菊花即可。若為後者,將所有滿足dx,1+dx,n=d1,n的掛成一條鏈,其餘點直接與鏈上點相連即可,相連點需要滿足dx,1-dx,n=dy,1-dy,n

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace
std; #define ll long long #define N 500010 #define D 1000010 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int x=0,f=1;char c=getchar(); while (c<'
0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int n,a[N],b[N],id[D]; struct data { int x,i; bool operator <(const data&a) const { return x<a.x; } }d[N]; int main() { #ifndef ONLINE_JUDGE freopen(
"bzoj5100.in","r",stdin); freopen("bzoj5100.out","w",stdout); const char LL[]="%I64d\n"; #else const char LL[]="%lld\n"; #endif n=read(); for (int i=2;i<n;i++) a[i]=read(); for (int i=2;i<n;i++) b[i]=read(); if (n==2) {cout<<"TAK\n"<<endl<<1<<' '<<2<<' '<<1;return 0;} int len=abs(a[2]-b[2]); for (int i=3;i<n;i++) if (abs(a[i]-b[i])!=len) {len=0;break;} if (len) { cout<<"TAK\n"; cout<<1<<' '<<n<<' '<<len<<endl; for (int i=2;i<n;i++) if (a[i]>b[i]) printf("%d %d %d\n",i,n,b[i]); else printf("%d %d %d\n",i,1,a[i]); return 0; } len=2000000; for (int i=2;i<n;i++) len=min(len,a[i]+b[i]); int cnt=0;for (int i=2;i<n;i++) if (a[i]+b[i]==len) cnt++,d[cnt].x=a[i],d[cnt].i=i; sort(d+1,d+cnt+1);++cnt;d[0].x=0,d[0].i=1,d[cnt].x=len,d[cnt].i=n; for (int i=1;i<=cnt;i++) if (d[i].x==d[i-1].x) {cout<<"NIE";return 0;} for (int i=0;i<=cnt;i++) id[d[i].x]=d[i].i; for (int i=2;i<n;i++) if (a[i]+b[i]>len&&((a[i]+b[i]-len&1)||!id[a[i]-(a[i]+b[i]-len>>1)])) {cout<<"NIE";return 0;} cout<<"TAK\n"; for (int i=1;i<=cnt;i++) printf("%d %d %d\n",d[i-1].i,d[i].i,d[i].x-d[i-1].x); for (int i=2;i<n;i++) if (a[i]+b[i]>len) printf("%d %d %d\n",id[a[i]-(a[i]+b[i]-len>>1)],i,a[i]+b[i]-len>>1); return 0; }