为什么这份代码在本地(开了O2)跑了五六次都是2000ms以内,但是尼姑的测评机直接超了2.2s?
#include<bits/stdc++.h>//没判自环
using namespace std;
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
char *p1,*p2,buf[1<<20+5];
inline int read(){
int x=0;
char c=gc();
while(!isdigit(c)){
c=gc();
}while(isdigit(c)){
x=x*10+(c^48);
c=gc();
}return x;
}
using pi=pair<int,int>;
const int N=1e5+5;
int n,vis[N],pr[N][2],rnk[N],fg,Fg,a[N<<1],len,ct;
long long f1[N],f2[N],dep[N],sum[N],tr[N<<3][2],d[N];
double ans=LONG_LONG_MAX;
vector<pi>e[N];
vector<int>w;
void add(int p,int x,long long y,int z,int s,int t){
if(s==t){
tr[p][z]=y;
return;
}
int mid=s+t>>1;
if(x<=mid)add(p<<1,x,y,z,s,mid);
else add(p<<1|1,x,y,z,mid+1,t);
tr[p][z]=max(tr[p<<1][z],tr[p<<1|1][z]);
}
long long ask(int p,int l,int r,int x,int s,int t){
if(r<s||t<l)return LONG_LONG_MIN;
if(l<=s&&t<=r)return tr[p][x];
int mid=s+t>>1;
return max(ask(p<<1,l,r,x,s,mid),ask(p<<1|1,l,r,x,mid+1,t));
}
void dfs0(int u,int fa){
for(pi v:e[u])
if(v.first!=fa){
pr[v.first][0]=u;
pr[v.first][1]=v.second;
dep[v.first]=dep[u]+v.second;
dfs0(v.first,u);
f1[u]=max(f1[u],f1[v.first]+v.second);
}
}
void dfs(int u,int fa){
if(fg)return;
if(vis[u]){
fg=1;
w.push_back(u);
rnk[u]=1;
for(int x=pr[u][0];x!=u;x=pr[x][0]){
w.push_back(x);
rnk[x]=1;
}
return;
}
vis[u]=1;
for(pi v:e[u])
if(v.first!=fa){
pr[v.first][0]=u;
pr[v.first][1]=v.second;
dfs(v.first,u);
if(fg)break;
}
}
void dfs2(int u,int fa){
long long m1=0,m2=0;
for(pi v:e[u])
if(v.first!=fa){
if(f1[v.first]+v.second>m1){
m2=m1;
m1=f1[v.first]+v.second;
}
else if(f1[v.first]+v.second>m2)m2=f1[v.first]+v.second;
}
for(pi v:e[u])
if(v.first!=fa){
f2[v.first]=v.second+max((m1==f1[v.first]+v.second?m2:m1),f2[u]);
if(f2[v.first]<=f1[v.first])ans=min(ans,1.0*f1[v.first]);
else if(f2[v.first]-v.second>=f1[v.first]+v.second)ans=min(ans,1.0*(f2[v.first]-v.second));
else ans=min(ans,1.0*(f2[v.first]+f1[v.first])/2);
dfs2(v.first,u);
}
}
int main(){
n=read();
for(int i=1;i<=n;i++){
int x=read(),y=read(),z=read();
e[x].push_back({y,z});
e[y].push_back({x,z});
}
dfs(1,0);
for(int i:w)
for(pi j:e[i])
if(!rnk[j.first]){
pr[j.first][0]=i;
pr[j.first][1]=j.second;
dep[j.first]=j.second;
dfs0(j.first,i);
f1[i]=max(f1[i],f1[j.first]+j.second);
}
len=ct=w.size();
for(int i=0;i<len;i++)a[i+1]=a[i+1+len]=pr[w[i]][1];
len<<=1;
for(int i=1;i<len;i++)sum[i+1]=sum[i]+a[i];
for(int i=1;i<=len;i++){
add(1,i,f1[w[(i-1)%ct]]-sum[i],0,1,len);
add(1,i,f1[w[(i-1)%ct]]+sum[i],1,1,len);
}
for(int i=1;i<len;i++){
int l=(i>ct?i-ct-1:0),r=(i+1>ct?ct-2:i-1),mid;
while(l<=r){
mid=l+r>>1;
if(sum[i]+ask(1,i-mid,i,0,1,len)>ask(1,i+1,i+ct-1-mid,1,1,len)-sum[i+1])r=mid-1;
else l=mid+1;
}
long long x=sum[i]+ask(1,i-r,i,0,1,len),y=ask(1,i+1,i+ct-1-r,1,1,len)-sum[i+1];
if(r>=(int)(i>ct?i-ct-1:0)){
if(x+a[i]<=y)ans=min(ans,1.0*y);
else if(y+a[i]<=x)ans=min(ans,1.0*x);
else ans=min(ans,1.0*(x+y+a[i])/2);
}
if(r<(int)(i+1>ct?ct-2:i-1)){
r++;
x=sum[i]+ask(1,i-r,i,0,1,len),y=ask(1,i+1,i+ct-1-r,1,1,len)-sum[i+1];
if(x+a[i]<=y)ans=min(ans,1.0*y);
else if(y+a[i]<=x)ans=min(ans,1.0*x);
else ans=min(ans,1.0*(x+y+a[i])/2);
}
}
for(int i:w)d[i]=LONG_LONG_MAX;
for(int i=1;i<=len;i++){
add(1,i,-sum[i],0,1,len);
add(1,i,sum[i],1,1,len);
int l=(i>ct?i-ct-1:0),r=(i>ct?ct-1:i-1),mid;
while(l<=r){
mid=l+r>>1;
if(sum[i]+ask(1,i-mid,i,0,1,len)>ask(1,i,i+ct-1-mid,1,1,len)-sum[i])r=mid-1;
else l=mid+1;
}
if(r>=(int)(i>ct?i-ct-1:0))d[w[(i-1)%ct]]=min(d[w[(i-1)%ct]],max(sum[i]+ask(1,i-r,i,0,1,len),ask(1,i,i+ct-1-r,1,1,len)-sum[i]));
if(r<(int)(i>ct?ct-1:i-1)){
r++;
d[w[(i-1)%ct]]=min(d[w[(i-1)%ct]],max(sum[i]+ask(1,i-r,i,0,1,len),ask(1,i,i+ct-1-r,1,1,len)-sum[i]));
}
add(1,i,f1[w[(i-1)%ct]]-sum[i],0,1,len);
add(1,i,f1[w[(i-1)%ct]]+sum[i],1,1,len);
}
for(int u:w){
long long m1=0,m2=0;
for(pi v:e[u]){
if(rnk[v.first])continue;
if(f1[v.first]+v.second>m1){
m2=m1;
m1=f1[v.first]+v.second;
}
else if(f1[v.first]+v.second>m2)m2=f1[v.first]+v.second;
}
for(pi v:e[u]){
if(rnk[v.first])continue;
f2[v.first]=v.second+max(f1[v.first]+v.second==m1?m2:m1,d[u]);
if(f1[v.first]+v.second<=f2[v.first]-v.second)ans=min(ans,1.0*(f2[v.first]-v.second));
else if(f1[v.first]>=f2[v.first])ans=min(ans,1.0*f1[v.first]);
else ans=min(ans,1.0*(f1[v.first]+f2[v.first])/2);
dfs2(v.first,u);
}
}
printf("%.1lf",ans);
return 0;
}