我自己写的代码AC和WA交错。然后我去看题解,我看见第一篇题解的斜率是直接相除,我觉得有精度误差,把它改成对角相乘后就WA了。
然后我检查了 long long 以及乘过去的 x 是否为负数,没有发现任何问题。而且这道题坐标的范围是 106 ,相乘后是 1012 不会爆 long long。
神仙们请问一下哪里错了?万分感谢!!!
第一篇题解的代码:斜率直接相除,AC:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double
const int N=1e5+5;
const ld eps=1e-10;
ll n,m,k,sidx,ans;
struct seg{
int x,y;
bool operator < (const seg &v) const{
return x!=v.x?x<v.x:y>v.y;
}
}s[N];
ll K,f[N],g[N],num[N];
ll squ(ll x){return x*x;}
ll Y(int i){return f[i]+squ(s[i+1].x)-g[i]-K;}
ll X(int i){return s[i+1].x;}
ld slope(int i,int j){return (ld)(Y(j)-Y(i))/(X(j)-X(i));}
ll hd,tl,d[N];
bool check(){
d[hd=tl=1]=0;
for(int i=1;i<=n;i++){
while(hd<tl&&slope(d[hd],d[hd+1])+eps<=2*s[i].y)hd++;
int j=d[hd]; num[i]=num[j]+1,f[i]=f[j]+squ(s[i].y-s[j+1].x)-g[j]-K;
if(i<n)while(hd<tl&&slope(d[tl-1],d[tl])-eps>=slope(d[tl],i))tl--;
d[++tl]=i;
} return num[n]<=k;
}
int main(){
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
cin>>s[i].x>>s[i].y;
if(s[i].x>s[i].y)swap(s[i].x,s[i].y);
}
sort(s+1,s+n+1);
for(int i=1,r=-1;i<=n;i++)if(s[i].y>r)r=s[i].y,s[++sidx]=s[i]; n=sidx;
for(int i=1;i<n;i++)if(s[i].y>=s[i+1].x)g[i]=squ(s[i].y-s[i+1].x+1);
for(int i=1;i<=n;i++)s[i].y++;
ll l=-1e12,r=0;
while(l<=r)
{
K=l+r>>1;
if(check()) l=K+1,ans=f[n]+K*k;
else r=K-1;
}
cout<<ans<<endl;
return 0;
}
对角相乘的代码,WA:
#include <bits/stdc++.h>
using namespace std;
typedef __int128 i128;
#define int long long //检查long long
#define ll long long
#define ld long double
const int N=1e5+5;
ll n,m,k,sidx,ans;
struct seg{
int x,y;
bool operator < (const seg &v) const{
return x!=v.x?x<v.x:y>v.y;
}
}s[N];
ll K,f[N],g[N],num[N];
ll squ(ll x){return x*x;}
ll Y(int i){return f[i]+squ(s[i+1].x)-g[i]-K;}
ll X(int i){return s[i+1].x;}
ld slope(int i,int j){return (ld)(Y(j)-Y(i))/(X(j)-X(i));}
ll hd,tl,d[N];
bool check(){
d[hd=tl=1]=0;
for(int i=1;i<=n;i++){
//下面的代码是检查负数。提交结果是没有输出任何下面的字符
if(X(d[hd+1])-X(d[hd])<0) puts("!!!");
if(i<n && X(i)-X(d[tl])<0) puts("@@@");
if(i<n && X(d[tl])-X(d[tl-1])<0) puts("???");
while(hd<tl&& (i128(Y(d[hd+1])-Y(d[hd])))<=(i128(X(d[hd+1])-X(d[hd]))*2*s[i].y))hd++;
int j=d[hd]; num[i]=num[j]+1,f[i]=f[j]+squ(s[i].y-s[j+1].x)-g[j]-K;
if(i<n)while(hd<tl&&(i128(Y(d[tl])-Y(d[tl-1]))*(X(i)-X(d[tl])))>=(i128(X(d[tl])-X(d[tl-1]))*(Y(i)-Y(d[tl])))) tl--;
d[++tl]=i;
} return num[n]<=k;
}
signed main(){
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
cin>>s[i].x>>s[i].y;
if(s[i].x>s[i].y)swap(s[i].x,s[i].y);
}
sort(s+1,s+n+1);
for(int i=1,r=-1;i<=n;i++)if(s[i].y>r)r=s[i].y,s[++sidx]=s[i]; n=sidx;
for(int i=1;i<n;i++)if(s[i].y>=s[i+1].x)g[i]=squ(s[i].y-s[i+1].x+1);
for(int i=1;i<=n;i++)s[i].y++;
ll l=-1e12,r=0;
while(l<=r)
{
K=l+r>>1;
if(check()) l=K+1,ans=f[n]+K*k;
else r=K-1;
}
cout<<ans<<endl;
return 0;
}