题目大意
给定正整数 \(a_1,a_2,\dots,a_n\)。构造 \(n+2\) 个点 \(P_0,P_1,\dots,P_{n+1}\),使得
\S_{\\triangle P_{i-1}P_iP{i+1}}=a_i \\
并且这些点按照给定顺序组成严格凸多边形。
解题思路
设点 \(P_i\) 的坐标为 \((x_i,y_i)\)。
我们希望直接用坐标表示三角形面积。
看到三角形面积,想到行列式,三角形面积可以用行列式的绝对值表示
\S_{\\triangle P_{i-1}P_iP{i+1}}=\\frac{1}{2}\\left\| \\begin{vmatrix} x_i-x_{i-1}\&y_i-y_{i-1}\\\\ x_{i+1}-x_i\&y_{i+1}-y_i \\end{vmatrix}\\right\| \\
我们有 \(2n+4\) 个坐标变量,面积限制只有 \(n\) 个。显然满足题意的构造可以有很多种。
重要思维模式:既然题目允许任意构造,为什么不主动牺牲一些自由度,换取表达式的简单?
二阶行列式满足
\\\det\\left( \\begin{bmatrix} a\&b\\\\ c\&d \\end{bmatrix}\\right)=ad-bc \\
如果我们让
\x_i-x_{i-1}=x_{i+1}-x_i=1 \\
就能化简表达式,不妨令 \(x_i=i\)。这样一来点的坐标变成 \((i,y_i)\)。
然后,题目中限制化简为
\\|(y_{i+1}-y_i)-(y_i-y_{i-1})\|=2a_i \\
左侧正是 \(y\) 数列的二阶差分的绝对值。
然后直接对着 \(2a_i\) 数列做两边前缀和就结束了。
因为二阶差分严格 \(>0\),所以一阶差分严格递增,构造出来的一定是严格凸多边形,满足题意。
Code
cpp
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
long long a[N];
int n;
signed main(){
cin>>n;
for(int i=2;i<=n;++i) cin>>a[i],a[i]*=2;
partial_sum(a,a+n+2,a);
partial_sum(a,a+n+2,a);
for(int i=0;i<=n+1;++i) cout<<i<<' '<<a[i]<<'\n';
return 0;
}