题面

一道比较神仙的构造题。

首先确定 \(1\) 到 \(n\) 的路径长度,不妨设其长为 \(m\) 。

通过观察发现,\(m\) 就是 \(\min_{1<i<n}\{dist_{1,i} + dist_{i,n}\}\)。

如果所有的 \(| dist_{1, i} - dist_{i, n} |\) 都相等,那么可以特判一下:

  • 首先将 \(1\) 与 \(n\) 连接起来,路径长度为 \(| dist_{1, i} - dist_{i, n} |\) ;
  • 对于每一个 \(\forall 1<i<n\) :
    • 如果\(dist_{1,i}>dist_{i,n}\),那么将 \(i\) 与 \(1\) 连接,长度为 \(dist_{1,i}\) ;
    • 如果\(dist_{1,i} \leq dist_{i,n}\) ,那么将 \(i\) 与 \(n\)连接,长度为 \(dist_{i, n}\) 。

若点 \(i\) 满足 \(dist_{1,i} + dist_{i,n} = m\),则 \(i\) 在 \(1\) 到 \(n\) 的路径上。

否则可以求出 \(i\) 到 \((1, n)\) 路径的距离和 \(i\) 在路径上的“投影”的

位置,查找位置可以使用二分查找。

将 \(i\) 挂在路径上对应的点上即可。

如果找不到可以挂起的位置或者 \(1\) 到 \(n\) 的路径上有几个点重复就无解。

注意特判 \(n=2\) 的情况。

代码如下(刚好 \(100\) 行…):

#include <bits/stdc++.h>
#define DEBUG fprintf(stderr, "Passing [%s] line %d\n", __FUNCTION__, __LINE__)
#define itn int
#define gI gi
#define mk make_pair using namespace std; inline int gi()
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return f * x;
} const int maxn = 500003; int sz, ddd, len, n, m = 1000000007, d1[maxn], dn[maxn], dis[maxn], jlx[maxn]; struct Node
{
int id, dis;
} a[maxn];
struct Ans
{
int u, v, w;
} ans[maxn]; inline bool cmp(Node x, Node y) {return x.dis < y.dis;} inline void sub1_getans()
{
puts("TAK");
printf("1 %d %d\n", n, len);
for (int i = 2; i < n; i+=1)
{
if (d1[i] < dn[i]) printf("1 %d %d\n", i, d1[i]);
else printf("%d %d %d\n", n, i, dn[i]);
}
return;
} inline int Binary_Search(int x)
{
int l = 1, r = sz;
while (l <= r)
{
int mid = (l + r) >> 1;
if (a[mid].dis == x) return mid;
else if (a[mid].dis < x) l = mid + 1;
else r = mid - 1;
}
return -1;
} int main()
{
n = gi();
if (n == 2) //特判
{
puts("TAK\n1 2 1");
return 0;
}
d1[1] = dn[n] = 0;
for (int i = 2; i < n; i+=1) d1[i] = gi();
for (int i = 2; i < n; i+=1) dn[i] = gi(), jlx[i] = abs(d1[i] - dn[i]);
bool fl = true;
for (int i = 3; i < n; i+=1) if (jlx[i] != jlx[i - 1]) {fl = false; break;}
if (fl) {len = jlx[2]; sub1_getans(); return 0;} //特判
for (int i = 2; i < n; i+=1) m = min(m, d1[i] + dn[i]);
a[++sz] = (Node){1, 0};
d1[n] = dn[1] = m;
for (int i = 2; i < n; i+=1)
if (d1[i] + dn[i] == m) a[++sz] = (Node){i, d1[i]};
a[++sz] = (Node){n, d1[n]};
sort(a + 1, a + 1 + sz, cmp);
for (int i = 2; i < n; i+=1)
{
dis[i] = d1[i] - (d1[i] + dn[i] - m) / 2;
}
for (int i = 1; i < sz; i+=1)
{
if (a[i].dis == a[i + 1].dis) {puts("NIE"); return 0;}
ans[++ddd] = (Ans){a[i].id, a[i + 1].id, a[i + 1].dis - a[i].dis};
}
for (int i = 2; i < n; i+=1)
{
int nowlen = d1[i] + dn[i];
if (nowlen != m)
{
int find_jl = Binary_Search(dis[i]); //二分挂起的位置
if (((d1[i] + dn[i] - m) & 1) || find_jl == -1) {puts("NIE"); return 0;}
ans[++ddd] = (Ans){a[find_jl].id, i, (d1[i] + dn[i] - m) / 2};
}
}
puts("TAK");
for (int i = 1; i <= ddd; i+=1) printf("%d %d %d\n", ans[i].u, ans[i].v, ans[i].w);
return 0;
}

另:这份代码在洛谷上 AC 了, 但是在 BZOJ 上会 WA, 不知道为什么……

题解【洛谷P5959】[POI2018]Plan metra的更多相关文章

  1. 【BZOJ5100】[POI2018]Plan metra 构造

    [BZOJ5100][POI2018]Plan metra Description 有一棵n个点的无根树,每条边有一个正整数权值,表示长度,定义两点距离为在树上的最短路径的长度. 已知2到n-1每个点 ...

  2. bzoj5100 [POI2018]Plan metra 构造

    5100: [POI2018]Plan metra Time Limit: 40 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 189  Sol ...

  3. bzoj千题计划249:bzoj5100: [POI2018]Plan metra

    http://www.lydsy.com/JudgeOnline/problem.php?id=5100 1.找到d1[i]+dn[i] 最小的点,作为1到n链上的点 2.令链长为D,若abs(d1[ ...

  4. 题解 洛谷P5018【对称二叉树】(noip2018T4)

    \(noip2018\) \(T4\)题解 其实呢,我是觉得这题比\(T3\)水到不知道哪里去了 毕竟我比较菜,不大会\(dp\) 好了开始讲正事 这题其实考察的其实就是选手对D(大)F(法)S(师) ...

  5. 题解 洛谷 P3396 【哈希冲突】(根号分治)

    根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...

  6. 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)

    题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...

  7. 题解-洛谷P4229 某位歌姬的故事

    题面 洛谷P4229 某位歌姬的故事 \(T\) 组测试数据.有 \(n\) 个音节,每个音节 \(h_i\in[1,A]\),还有 \(m\) 个限制 \((l_i,r_i,g_i)\) 表示 \( ...

  8. 题解-洛谷P4724 【模板】三维凸包

    洛谷P4724 [模板]三维凸包 给出空间中 \(n\) 个点 \(p_i\),求凸包表面积. 数据范围:\(1\le n\le 2000\). 这篇题解因为是世界上最逊的人写的,所以也会有求凸包体积 ...

  9. 题解-洛谷P4859 已经没有什么好害怕的了

    洛谷P4859 已经没有什么好害怕的了 给定 \(n\) 和 \(k\),\(n\) 个糖果能量 \(a_i\) 和 \(n\) 个药片能量 \(b_i\),每个 \(a_i\) 和 \(b_i\) ...

随机推荐

  1. Go String

    在 Go 语言中, 字符串是基础数据类型之一, 关键字为 string. 变量声明 字符串变量的声明如下: // 声明一个字符串类型的变量 s, 未赋予初始值时默认为零值"" va ...

  2. Exception in thread "main" java.lang.NoClassDefFoundError:org/springframework/beans/factory/config/EmbeddedValueResoler

    参考自:https://www.cnblogs.com/quanbin/p/11100337.html 解决方法:检查发现spring的核心包spring-bean版本和其他核心包版本不同,更改为和其 ...

  3. Django如何连接mysql

    1.设置django的mysql驱动为pymysql 因为django默认的是使用MySqlDb连接mysql数据库,但是由于该模块不支持python3.4以上版本,所以使用pymysql模块 在项目 ...

  4. JavaScript语法规则+JavaScript数据类型

    JavaScript: ECMAScript + BOM +DOM javascript 标识符命名规则: 1.只能是字母.数字.下划线.$ 2.不能以数字开头 3.不能使用关键字和保留字 省略var ...

  5. 【Git】git使用 - 冲突conflict的解决演示

    冲突的解决 (如果git使用不熟练)建议在push不了时,pull之前.在本地创建一个新的分支并commit到local,以保证本地有commit记录,万一出什么问题,可以找回代码,以免代码丢失. ( ...

  6. if、counf、countif、countifs、sumif、sumifs

    评分等级:=IF(C3>=90,"优秀",IF(C3>=80,"良好",IF(C3>=60,"及格","不及格& ...

  7. maven发布java-分支构建

    1.安装parameter插件 2. 新建maven项目 3.配置maven项目 4.配置maven项目2 5.配置maven项目3 6. 模拟开发给提交打tag标签 7.版本发布 8.tag获取并构 ...

  8. java网页日期选择框对应的星期有误

    · 我用java写了个星期查询代码,有的日期对有的日期错,求帮忙看看哪里有问题!! import java.util.*;public class Test1 {public static void ...

  9. 1级搭建类113-Oracle 11gR2 SI FS(OEL 6.10)

    Oracle 11g 单实例文件系统搭建(EMDC) EMDC:Database Control 单实例主机.数据库等监控,这东西12c之后没有了 EMGC:Grid Control 单独安装GC软件 ...

  10. 洛谷P1402 酒店之王(网络流)

    ### 洛谷P1402 题目链接 ### 题目大意:有 n 个人, p 间房间,q 种食物.每个人喜欢一些房间,一些食物,但每间房间.每种食物只能分配给一个人.问最大可以让多少个人满足(当且仅当分配到 ...