这是 18 分被卡精度的代码:
#include<bits/stdc++.h>
#define re register
using namespace std;
inline int read(){
re int t=0;re char v=getchar();
while(v<'0')v=getchar();
while(v>='0')t=(t<<3)+(t<<1)+v-48,v=getchar();
return t;
}
int n,a[100002],stk[100002],tp;
inline bool cmp(re int x,re int y,re int z){return 1ll*(a[x]-a[y])*(y-z)>1ll*(a[y]-a[z])*(x-y);}
int main(){
n=read();
for(re int i=1;i<=n;++i)a[i]=read();
stk[tp=1]=1;
for(re int i=2;i<=n+1;++i){
while(tp&&cmp(i,stk[tp],stk[tp-1]))--tp;
stk[++tp]=i;
}
for(re int i=1;i<=tp;++i){
re int l=stk[i-1],r=stk[i];
for(re int j=l+1;j<=r&&j<=n;++j)printf("%lld\n",100000ll*a[l]+100000ll*(a[r]-a[l])*(j-l)/(r-l));
}
}
这是 AC 代码
#include<bits/stdc++.h>
#define re register
using namespace std;
inline int read(){
re int t=0;re char v=getchar();
while(v<'0')v=getchar();
while(v>='0')t=(t<<3)+(t<<1)+v-48,v=getchar();
return t;
}
int n,a[100002],stk[100002],tp;
inline bool cmp(re int x,re int y,re int z){return 1ll*(a[x]-a[y])*(y-z)>1ll*(a[y]-a[z])*(x-y);}
int main(){
n=read();
for(re int i=1;i<=n;++i)a[i]=read();
stk[tp=1]=1;
for(re int i=2;i<=n+1;++i){
while(tp&&cmp(i,stk[tp],stk[tp-1]))--tp;
stk[++tp]=i;
}
for(re int i=1;i<=tp;++i){
re int l=stk[i-1],r=stk[i];
for(re int j=l+1;j<=r&&j<=n;++j)printf("%lld\n",(100000ll*a[l]*(r-l)+100000ll*(a[r]-a[l])*(j-l))/(r-l));
}
}
两份代码唯一的区别在于输出
一个是
printf("%lld\n",100000ll*a[l]+100000ll*(a[r]-a[l])*(j-l)/(r-l));
另一个是
printf("%lld\n",(100000ll*a[l]*(r-l)+100000ll*(a[r]-a[l])*(j-l))/(r-l));
没有使用 double,不应该出现精度误差,为什么这两个式子的计算结果会不一样,而且是下面的一个 AC?
应该不是炸 long long 的问题,因为所有变量都强转了 long long,并且如果要炸也是下面一个炸。
求大佬解答。