QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#415797#3047. Wind of ChangexlwangTL 0ms0kbC++146.9kb2024-05-21 10:31:322024-05-21 10:31:33

Judging History

你现在查看的是最新测评结果

  • [2024-05-21 10:31:33]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2024-05-21 10:31:32]
  • 提交

answer

#include<bits/stdc++.h>
#define ll long long
#define fr(i,j,k) for(register int i=j;i<=k;++i)
#define rf(i,j,k) for(register int i=j;i>=k;--i)
#define foredge(i,j) for(register int i=head[j];i;i=e[i].nxt)
#define pb push_back
#define Times printf("Time:%.3lf\n",clock()/CLOCKS_PER_SEC)
#define pii pair<int,int>
#define mk make_pair
using namespace std;
inline int read(){
	int x=0;
	bool f=0;
	char c=getchar();
	while(!isdigit(c)) f|=(c=='-'),c=getchar();
	while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return f?-x:x;
}
inline void write(int x){
    if(x<0){putchar('-');x=-x;}
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
inline void writeln(int x){write(x); puts("");}
inline void writepl(int x){write(x); putchar(' ');}
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
inline int randfind(int l,int r){return rnd()%(r-l+1)+l;}
//inline void init(){
//	int t=read();
//	while(t--) work();
//}
const int Maxn=1e6+10;
struct node{
    int nxt,to,d;
}e[Maxn<<1];
int head[Maxn],cnt;
inline void add(int u,int v,int w){++cnt;e[cnt].nxt=head[u];head[u]=cnt;e[cnt].to=v;e[cnt].d=w;}
int n;
struct edge{
    int d;
    int nxt,to,tp;
}e1[Maxn<<1];
int head1[Maxn],cnt1=1;
inline void add1(int u,int v,int w){++cnt1;e1[cnt1].nxt=head1[u];head1[u]=cnt1;e1[cnt1].to=v;e1[cnt1].d=w;e1[cnt1].tp=0;}
namespace DIS{
    int f[Maxn<<2][22];
    int lg[Maxn<<2];
    int dfn[Maxn],dep[Maxn];
    ll s[Maxn];
    int idx;
    inline int getmin(int x,int y){if(dep[x]<dep[y]) return x;return y;}
    inline void dfs(int x,int fa){
        dfn[x]=++idx;dep[x]=dep[fa]+1;f[idx][0]=x;
        for(register int i=head[x];i;i=e[i].nxt){
            int y;y=e[i].to;if(y==fa) continue;
            s[y]=s[x]+e[i].d;
            dfs(y,x);f[++idx][0]=x;
        }
    }
    inline void init(){
        dfs(1,0);
        lg[0]=-1;fr(i,1,idx) lg[i]=lg[i/2]+1;
        fr(j,1,lg[idx]) fr(i,1,idx){
            if(i+(1<<j)-1>idx) break;
            f[i][j]=getmin(f[i][j-1],f[i+(1<<(j-1))][j-1]);
        }
    }
    inline int getlca(int x,int y){
        x=dfn[x],y=dfn[y];
        if(x>y) swap(x,y);
        int ln=lg[y-x+1];
        return getmin(f[x][ln],f[y-(1<<ln)+1][ln]);
    }
    inline ll getdis(int x,int y){return s[x]+s[y]-2*s[getlca(x,y)];}
}
ll ans[Maxn];
inline void chkmin(ll &x,ll y){if(x>y) x=y;}
inline void update(int x,int y,ll k){chkmin(ans[x],k);chkmin(ans[y],k);}
int dfn[Maxn],idx;
vector<int> vc[Maxn];
int dep[Maxn];
inline void D(int x,int fa){
    dfn[x]=++idx;dep[x]=dep[fa]+1;
    for(register int i=head[x];i;i=e[i].nxt){
        int y;y=e[i].to;
        if(y==fa) continue;
        D(y,x);
    }
}
vector<int> point;
int a[Maxn],ln,col[Maxn];
ll pre[Maxn];
int stk[Maxn],top;
inline bool cmp(int a,int b){return dfn[a]<dfn[b];}
inline ll query(int x,int to){return pre[x]+DIS::getdis(x,to);}
inline void getnew(int &tp,int k,int x){
    if(!tp){tp=k;return;}
    if(query(tp,x)>query(k,x)) tp=k;
}
inline void getans(int x,int &tp1,int &tp2){
    // cerr<<x<<endl;
    if(col[x]){
        if(col[x]==1 && tp2) update(x,tp2,pre[x]+pre[tp2]+DIS::getdis(x,tp2));
        if(col[x]==2 && tp1) update(x,tp1,pre[x]+pre[tp1]+DIS::getdis(x,tp1));
        if(col[x]==1) getnew(tp1,x,x);
        if(col[x]==2) getnew(tp2,x,x);
    }
    int X,Y;
    X=tp1,Y=tp2;
    for(auto y:vc[x]){
        X=tp1,Y=tp2;
        getans(y,X,Y);
        if(tp1 && Y) update(tp1,Y,pre[tp1]+pre[Y]+DIS::getdis(tp1,Y));
        if(tp2 && X) update(tp2,X,pre[tp2]+pre[X]+DIS::getdis(tp2,X));
        getnew(tp1,X,x);getnew(tp2,Y,x);
    }
}
inline void solve(){
    sort(a+1,a+ln+1,cmp);
    // cout<<ln<<endl;
    // fr(i,1,ln) cout<<a[i]<<' ';cout<<endl;
    int llca=a[1];top=0;
    fr(i,1,ln) llca=DIS::getlca(llca,a[i]);
    if(llca!=a[1]) point.pb(llca),stk[++top]=llca;
    // cout<<llca<<' '<<a[1]<<endl;
    fr(i,1,ln){
        int x=a[i];
        // cout<<DIS::getlca(x,stk[top])
        while(top>1 && dep[DIS::getlca(x,stk[top])]<=dep[stk[top-1]]){
            point.pb(stk[top]);vc[stk[top-1]].pb(stk[top]);--top;
        }
        if(top==1){
            stk[++top]=x;
            continue;
        }
        if(dep[DIS::getlca(x,stk[top])]<dep[stk[top]]){
            int y=DIS::getlca(x,stk[top]);vc[y].pb(stk[top]);
            point.pb(stk[top]);stk[top]=y;
        }
        stk[++top]=x;
        // cout<<i<<' '<<top<<endl;
    }
    while(top>1) point.pb(stk[top]),vc[stk[top-1]].pb(stk[top]),--top;
    point.pb(stk[top]);
    int tp1,tp2;tp1=tp2=0;
    // puts("edge:");
    // fr(i,1,n){
    //     cout<<"id="<<i<<":\n";
    //     for(auto x:vc[i]) cout<<x<<' ';cout<<endl;
    // }
    getans(llca,tp1,tp2);
    for(auto x:point){col[x]=pre[x]=0;vector<int> ().swap(vc[x]);}
    vector<int> ().swap(point);
    ln=0;
}
int siz[Maxn];
int id,rt1,rt2,minn;
int siz1,siz2;
inline void findedge(int x,int fa,int Siz){
    siz[x]=1;
    for(register int i=head1[x];i;i=e1[i].nxt){
        if(e1[i].tp) continue;
        int y=e1[i].to;
        if(y==fa) continue;
        findedge(y,x,Siz);
        if(max(siz[y],Siz-siz[y])<minn){
            minn=max(siz[y],Siz-siz[y]);
            id=i;rt1=x;rt2=y;
            siz1=Siz-siz[y];siz2=siz[y];
        }
    }
}
inline void getpoint(int x,int fa,int color){
    if(x<=n) a[++ln]=x,col[x]=color;
    for(register int i=head1[x];i;i=e1[i].nxt){
        if(e1[i].tp) continue;
        int y=e1[i].to;
        if(y==fa) continue;
        pre[y]=pre[x]+e1[i].d;
        getpoint(y,x,color);
    }
}
inline void divide(int x,int Siz){
    // cerr<<x<<' '<<Siz<<endl;
    if(Siz==1) return;
    minn=Siz;findedge(x,0,Siz);
    int r1,r2;r1=rt1,r2=rt2;
    int s1,s2;s1=siz1;s2=siz2;
    pre[rt1]=e1[id].d;pre[rt2]=0;
    getpoint(rt1,rt2,1);getpoint(rt2,rt1,2);
    solve();
    e1[id].tp=e1[id^1].tp=1;
    divide(r1,s1);divide(r2,s2);
}
int ID;
inline void maketree(int x,int fa){
    int lst=x;
    for(register int i=head[x];i;i=e[i].nxt){
        int y;y=e[i].to;
        if(y==fa) continue;
        ++ID;
        add1(lst,ID,0);add1(ID,lst,0);
        add1(ID,y,e[i].d);add1(y,ID,e[i].d);
        lst=ID;maketree(y,x);
    }
}
inline void init(){
    n=read();ID=n;
    fr(i,1,n-1){
        int x,y,z;
        x=read();y=read();z=read();
        add(x,y,z);add(y,x,z);
    }
    maketree(1,0);
    memset(head,0,sizeof(head));cnt=0;
    fr(i,1,n-1){
        int x,y,z;
        x=read();y=read();z=read();
        add(x,y,z);add(y,x,z);
    }
    D(1,0);DIS::init();
}
inline void work(){
    // fr(i,1,ID) cout<<i<<' '<<dfn[i]<<endl;
    // fr(i,1,n) fr(j,1,n) cout<<i<<' '<<j<<' '<<DIS::getlca(i,j)<<endl;
    fr(i,1,n) ans[i]=1e17;
    divide(1,ID);
    fr(i,1,n) printf("%lld\n",ans[i]);
}
signed main(){
	// freopen("input.in","r",stdin);
	// freopen("output.out","w",stdout);
    init();work();
    // printf("\nTIME:%.3lf",(double)clock()/CLOCKS_PER_SEC);
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Time Limit Exceeded

input:

250000
137466 116241 624409157
188961 163586 148491970
13958 122239 46409636
186120 44010 919858866
72320 102560 92679302
158544 236582 882613876
22331 114267 646741536
210782 42861 679450428
56693 45397 898958944
71188 114724 904191407
15203 225401 210626781
31071 144225 278121829
110354 83972 4557...

output:


result: