学习Andrew算法后突然想起这一题。
这简直就是为Andrew算法量身订做的模板题。
因为Andrew算法是一半一半求凸包,而这题实际上只需要求右半边的凸包即可。
甚至题目给出的点都是排好序的,我们就不用费力去排序以及求另一半凸包了。
```#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
//#define int long long
//#define LL long long
#define pdd pair<double,double>
#define endl "\n"
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define VI vector<int>
#define VVI vector<vector<int>>
#define PII pair<int,int>
#define MII map<int,int>
#define MSI map<string,int>
#define MAXN 0x3f3f3f3f
#define MINN -0x3f3f3f3f
#define Gheap priority_queue<int>
#define Lheap priority_queue<int,vector<int>,greater<int>>
using namespace std;
//const int N=1e6+100;
//int e[N],w[M],ne[M],h[M],idx;
bool cmp(pdd x,pdd y)
{
return x.se!=y.se ? x.se<y.se : x.fi<y.fi;
}
double dis(pdd a,pdd b)
{
return sqrt((a.fi-b.fi)*(a.fi-b.fi)+(a.se-b.se)*(a.se-b.se));
}
double cross(pdd a,pdd b,pdd c)
{
return (b.fi-a.fi)*(c.se-a.se)-(b.se-a.se)*(c.fi-a.fi);
}
void solve()
{
int n,a;
double ans=0;
cin>>n;
pdd v[n+2];
pdd st[4*n];
int top=0;
for(int i=0;i<=n;i++)
{
cin>>a;
v[i]={a,i};
}
//sort(v,v+n+1,cmp);
for(int i=0;i<=n;i++)
{
while(top>1&&cross(st[top-1],st[top],v[i])<=0) top--;
st[++top]=v[i];
}
for(int i=2;i<=top;i++)
{
ans+=dis(st[i-1],st[i]);
}
printf("%.12lf",ans);
}
/*简直就是Andrew算法的模板题*/
/*WA十几发原来是ans没有初始化为0...*/
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
//cin >> t;
while(t--) solve();
}