90pts WA#3#4 求条,玄关

P1600 [NOIP2016 提高组] 天天爱跑步

OrinLoong @ 2025-01-10 19:22:43

#include <bits/stdc++.h>
using namespace std;
const int MaxN=3e5+5;
int frdint(){
    int n=0,k=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')k=-1;ch=getchar();}
    while(isdigit(ch))n=(n<<3)+(n<<1)+ch-'0',ch=getchar();
    return n*k;
}
void fwrint(int x){
    if(x<0)putchar('-'),x=-x;
    if(x>9)fwrint(x/10);
    putchar(x%10+'0');
}
int N,M,X,Y,W[MaxN];
vector<int> Ti[MaxN];
void addudge(int u,int v){
    Ti[u].push_back(v);
    Ti[v].push_back(u);
}
int dep[MaxN],tfa[MaxN],siz[MaxN],hvs[MaxN];
void dfs1(int u,int f){
    dep[u]=dep[f]+1,tfa[u]=f,siz[u]=1;
    for(int v : Ti[u]){
        if(v==f)continue;
        dfs1(v,u);siz[u]+=siz[v];
        if(siz[v]>siz[hvs[u]])hvs[u]=v;
    }
}
int top[MaxN];
void dfs2(int u,int t){
    top[u]=t;if(!hvs[u])return;
    dfs2(hvs[u],t);for(int v : Ti[u]){
        if(v!=tfa[u]&&v!=hvs[u])dfs2(v,v);
    }
}
int getlca(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        x=tfa[top[x]];
    }
    return dep[x]<dep[y]?x:y;
}
struct anob{int s,t,d;}P[MaxN];
int buc[2][MaxN<<1],ans[MaxN];
vector<int> avec[MaxN],svec[MaxN],tvec[MaxN];
void dfs3(int u){
    // printf("u=%d,",u);
    int tmp1=buc[0][dep[u]+W[u]],tmp2=buc[1][dep[u]-W[u]+N];
    // printf("tmp1=%d,tmp2=%d\n",tmp1,tmp2);
    for(int v : Ti[u])if(v!=tfa[u])dfs3(v);
    // printf("%d::::\n",u);
    buc[0][dep[u]]+=svec[u].size();
    // printf("buc[0][%d]+=%d\n",dep[u],svec[u].size());
    for(int i : tvec[u]){
        buc[1][dep[u]-P[i].d+N]++;
        // printf("buc[1][%d]++\n",dep[u]-P[i].d);
    }
    // if(u==1&&buc[0])
    // ans[u]+=buc[0][dep[u]+W[u]]-tmp1+buc[1][dep[u]-W[u]+N]-tmp2;

    int cres=buc[0][dep[u]+W[u]]-tmp1+buc[1][dep[u]-W[u]+N]-tmp2;
    // if(cres<0&&u==1)printf("ERR! cres=%d\n",cres);
    if(cres>=0)ans[u]+=cres;
    // printf("ansu+=rbuc[0][%d]\n",W[u]+dep[u]);
    // printf("ansu+=rbuc[1][%d]\n",dep[u]-W[u]);
    for(int i : avec[u])buc[0][dep[P[i].s]]--;
    // printf("buc[0][%d]--\n",dep[P[i].s]);
    for(int i : avec[u])buc[1][dep[P[i].t]-dep[P[i].d]+N]--;
    // printf("buc[1][%d]--\n",dep[P[i].t]-dep[P[i].d]);
}
int main(){
    // freopen("P1600_3.in","r",stdin);
    // freopen("myans1.out","w",stdout);
    N=frdint(),M=frdint();
    for(int i = 1;i < N;i++){
        X=frdint(),Y=frdint();
        addudge(X,Y);
    }
    for(int i = 1;i <= N;i++)W[i]=frdint();
    dfs1(1,0),dfs2(1,1);
    for(int i = 1;i <= M;i++){
        auto &[cs,ct,cd]=P[i];
        cs=frdint(),ct=frdint();
        svec[cs].push_back(i);
        tvec[ct].push_back(i);
        int anc=getlca(cs,ct);
        avec[anc].push_back(i);
        cd=dep[cs]+dep[ct]-dep[anc]*2;
        // printf("cd[%d]=%d\n",i,cd);
        if(dep[anc]+W[anc]==dep[cs]){
            ans[anc]--;
            // if(anc==1)printf("a1-- by %d:{%d,%d,%d}\n",i,cs,ct,cd);
        }
        // printf("bao[%d]!\n",anc);
    }
    dfs3(1);
    for(int i = 1;i <= N;i++){
        fwrint(ans[i]),putchar(' ');
    }
    // int x=frdint();
    return 0;
}

求条。


|