社区讨论

诡异的被卡

P2680[NOIP 2015 提高组] 运输计划参与者 2已保存回复 9

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
9 条
当前快照
1 份
快照标识符
@mi6llm7g
此快照首次捕获于
2025/11/20 06:52
4 个月前
此快照最后确认于
2025/11/20 06:52
4 个月前
查看原帖
用二分,树上差分,倍增lca搞的
除了13个点以外都跑的很快 但是本地测试第13个点 2分钟仍然跑不出来
看了性能分析,发现大部分时间浪费在dfs上,但不是最多只有边数乘2的复杂度吗
所以是怎么被卡了?
求各位大佬指教
CPP
#include<cstdio>
#include<cstring>
#define MAXN 500000
#define MAXE 500000
#define MAXP 500000
#define MAXLOG 16
int n,m;
inline char nc(){
  static char buf[100000],*p1=buf,*p2=buf;
  return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
template <typename T>
inline void Read(T &x){
    x=0;int p=1;char c=nc();
    for(;!('0'<=c&&c<='9');c=nc()); 
    for(;'0'<=c&&c<='9';c=nc()) x=x*10+c-'0';
}
struct Edge{
    int v,w,nxt;
    Edge(){}
    Edge(int _v,int _w,int _nxt):v(_v),w(_w),nxt(_nxt){}
}E[MAXE+10];int nE,head[MAXE+10],node[MAXN+10],nodeIndex;
inline void Link(int u,int v,int w){
    E[nE]=Edge(v,w,head[u]);head[u]=nE++;
    E[nE]=Edge(u,w,head[v]);head[v]=nE++;
}
int dep[MAXN+10],pfa[MAXN+10][MAXLOG],dis[MAXN+10],len[MAXN+10],cnt[MAXN+10];
int stack[MAXN+10],top;
inline int haha(){
    return 0;
}
void dfs(int u){
    stack[++top]=u;
    while(top){
        u=stack[top--];node[++nodeIndex]=u;
        for(int j=1;j<=MAXLOG&&(1<<j)<=dep[u];j++)
            pfa[u][j]=pfa[pfa[u][j-1]][j-1];
        for(int i=head[u],v=E[i].v,k;i!=-1;i=E[i].nxt,v=E[i].v) if(pfa[u][0]!=v){
            pfa[v][0]=u;dep[v]=dep[u]+1;
            dis[v]=dis[u]+E[i].w;len[v]=E[i].w;
            stack[++top]=v;
        }
    }
}
int q[MAXN+10],front,tail;
struct Plan{
    int u,v,lca,dis;
    Plan(){}
    Plan(int _u,int _v,int _lca,int _dis):u(_u),v(_v),lca(_lca),dis(_dis){}
}P[MAXP+10];int nP;
int lca(int u,int v){
    if(dep[u]<dep[v]){int t=u;u=v;v=t;}
    int d=dep[u]-dep[v];
    for(int i=0;(1<<i)<=d;i++) if(d&(1<<i)) u=pfa[u][i];
    if(u==v) return u;
    for(int i=MAXLOG-1;i>=0;i--)
        if(pfa[u][i]!=pfa[v][i]) u=pfa[u][i],v=pfa[v][i];
    return pfa[u][0];
}
bool Check(int val){
    memset(cnt,0,sizeof(cnt));
    int flag=0,limit=0;
    for(int i=1;i<=nP;i++)if(P[i].dis>val){
        cnt[P[i].u]++,cnt[P[i].v]++,cnt[P[i].lca]-=2;
        if(limit<P[i].dis-val) limit=P[i].dis-val;
        flag++;
    }
    if(!flag) return true;
    for (int i=n;i>1;i--) cnt[pfa[node[i]][0]]+=cnt[node[i]];
    for (int i=2;i<=n;i++)
        if(len[i]>=limit&&cnt[i]==flag) return true;
    return false;
}
int main(){
    memset(head,-1,sizeof(head));
    int l=0,r=0,mid,ans=0;
    int maxlen=0,maxdis=0;
    scanf("%d%d",&n,&m);
    for(int i=1,x,y,z;i<n;i++){
        Read(x);Read(y);Read(z);
        Link(x,y,z);
        if(z>maxlen) maxlen=z;
    }
    dfs(1);
    for(int i=1,t,x,y;i<=m;i++){
        Read(x);Read(y);
        t=lca(x,y);
        P[++nP]=Plan(x,y,t,dis[x]+dis[y]-(dis[t]<<1));
        if(maxdis<P[i].dis) maxdis=P[i].dis;
    }
    l=maxdis-maxlen;r=maxdis;
    while(l<=r){
        mid=(l+r)>>1;
        if(Check(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    }
    printf("%d\n",ans);
    return 0;
}

回复

9 条回复,欢迎继续交流。

正在加载回复...