95pts 求卡常
查看原帖
95pts 求卡常
1209625
zyd22楼主2025/6/25 20:31

本人用过了快读快写,不起作用qwq

//#include<bits/stdc++.h>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
//#define int long long
using namespace std;
struct node{
    int u,v,ne,w;
}a[1001000];
int he[1001000],tot;
int n,m,q;
void add(int u,int v,int w){
    a[++tot].u=u;
    a[tot].v=v;
    a[tot].w=w;
    a[tot].ne=he[u];
    he[u]=tot;
}
int dep[501000];
int fa[501000][21];
int Mx[501000][21];
int sum[501000];
void dfs(int u,int f){
    for(int i=he[u];i;i=a[i].ne){
        int v=a[i].v;
        if(v==f) continue;
        dep[v]=dep[u]+1;
        fa[v][0]=u;
        sum[v]=sum[u]+a[i].w;
        Mx[v][0]=a[i].w;
        dfs(v,u);
    }
}
int LCA(int u,int v){
    if(u==v) return u;
    if(dep[u]<dep[v]) swap(u,v);
    for(int i=18;i>=0;i--){
        if(fa[u][i]&&dep[fa[u][i]]>=dep[v]) u=fa[u][i];
    }
    if(u==v) return u;
    for(int i=18;i>=0;i--){
        if(fa[u][i]&&fa[u][i]!=fa[v][i]){
            u=fa[u][i];
            v=fa[v][i];
        }
    }
    return fa[u][0];
}
int S[501000],T[501000],len[501000];
int st[501000],ed[501000];
pair<int,int> road[501000];
struct Tree{
    int l,r,s,t,lca;
}tree[2001000];
Tree up(Tree k1,Tree k2,Tree res){
    if(dep[k1.lca]>dep[k2.lca]) swap(k1,k2);
    res.s=res.t=res.lca=0;
    if(k1.lca==k2.lca){
        res.s=res.t=res.lca=k1.lca;
        pair<int,int> A[4]={{dep[LCA(k1.s,k2.s)],LCA(k1.s,k2.s)},{dep[LCA(k1.t,k2.t)],LCA(k1.t,k2.t)},{dep[LCA(k1.s,k2.t)],LCA(k1.s,k2.t)},{dep[LCA(k1.t,k2.s)],LCA(k1.t,k2.s)}};
        sort(A,A+4);
        res.s=A[3].second;
        res.t=A[2].second;
    }
    else if(LCA(k2.lca,k1.s)==k2.lca){
        res.s=LCA(k2.s,k1.s);
        res.t=LCA(k2.t,k1.s);
        res.lca=LCA(res.s,res.t);
    }
    else if(LCA(k2.lca,k1.t)==k2.lca){
        res.s=LCA(k2.s,k1.t);
        res.t=LCA(k2.t,k1.t);
        res.lca=LCA(res.s,res.t);
    }
    return res;
}
void build(int p,int l,int r){
    tree[p].l=l;
    tree[p].r=r;
    if(l==r){
        tree[p].s=S[l];
        tree[p].t=T[l];
        tree[p].lca=LCA(tree[p].s,tree[p].t);
        return;
    }
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    tree[p]=up(tree[p*2],tree[p*2+1],tree[p]);
}
Tree ask(int p,int l,int r){
    if(tree[p].l>=l&&tree[p].r<=r){
        return tree[p];
    }
    Tree res={0,0,0,0,0};
    int mid=(tree[p].l+tree[p].r)/2,f=0;
    if(mid>=l){
        res=ask(p*2,l,r);
        f=1;
    }
    if(mid+1<=r){
        if(f){
            res=up(res,ask(p*2+1,l,r),res);
        }
        else
            res=ask(p*2+1,l,r);
    }
    return res;
}
int findmax(int s,int t,int lca){
    if(s==t) return 0;
    int mx=0;
    for(int j=18;j>=0;j--){
        if(fa[s][j]&&dep[fa[s][j]]>=dep[lca]){
            mx=max(mx,Mx[s][j]);
            s=fa[s][j];
        }
    }
    for(int j=18;j>=0;j--){
        if(fa[t][j]&&dep[fa[t][j]]>=dep[lca]){
            mx=max(mx,Mx[t][j]);
            t=fa[t][j];
        }
    }
    return mx;
}
int check(int mid,int id){
    Tree res=ask(1,id,m);
    if(res.s==res.t) return 0;
    int mx=findmax(res.s,res.t,res.lca);
    if(len[m]-mx>mid) return 0;
    return 1;
}
signed main(){
    scanf("%d%d",&n,&m);
    int mxw=0;
    for(int i=1;i<n;i++){
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w);
        add(v,u,w);
        mxw=max(mxw,w);
    }
    dep[1]=1;
    dfs(1,0);
    for(int j=1;j<=18;j++){
        for(int i=1;i<=n;i++){
            fa[i][j]=fa[fa[i][j-1]][j-1];
            Mx[i][j]=max(Mx[i][j-1],Mx[fa[i][j-1]][j-1]);
        }
    }
    for(int i=1;i<=m;i++){
        scanf("%d%d",&st[i],&ed[i]);
        road[i].first=sum[st[i]]+sum[ed[i]]-2*sum[LCA(st[i],ed[i])];
        road[i].second=i;
    }
    sort(road+1,road+1+m);
    for(int i=1;i<=m;i++){
        len[i]=road[i].first;
        S[i]=st[road[i].second];
        T[i]=ed[road[i].second];
        //printf("%d ",len[i]);
    }
    build(1,1,m);
    int l=len[m]-mxw,r=len[m];
    while(l<r){
        int mid=(l+r)/2;
        int id=upper_bound(len+1,len+1+m,mid)-len;
        if(check(mid,id)){
            r=mid;
        }
        else{
            l=mid+1;
        }
        //printf("%d %d %d %d %d\n",l,r,mid,id,check(mid,id));
    }
    if(m==1){
        printf("%d\n",len[1]-findmax(S[1],T[1],LCA(S[1],T[1])));
        return 0;
    }
    printf("%d\n",l);
    return 0;
}
2025/6/25 20:31
加载中...