线段树合并70pts求条

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

EXR_FAL @ 2025-01-10 19:36:30

RT

WA on 6,7,8,9,11,12

//Ciallo~(∠・ω< )⌒★

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
inline ll read(){
   ll x=0,flag=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')flag=-1;ch=getchar();}
    while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    return x*flag;
}
void out(ll x){
    if(x<0)putchar('-'),x=-x;
    if(x<10)putchar(x+'0');
    else out(x/10),putchar(x%10+'0');
}

#define int long long
const int N=3e5+114;
const int M=N<<1;

int n,m,s;
int w[N],res[N];

//Graph
struct E{int to,nxt;}e[M];
int head[N],etot;
void add(int u,int v){
    e[++etot].to=v;
    e[etot].nxt=head[u];
    head[u]=etot;
}
void init(){
    for(int i=0;i<M;i++)
        e[i].nxt=-1;
    memset(head,-1,sizeof head);
}

//LCA~
int dep[N],fa[N][21];
void dfs(int u,int fat){
    dep[u]=dep[fat]+1;
    fa[u][0]=fat;
    for(int i=1;i<=20;i++)
        fa[u][i]=fa[fa[u][i-1]][i-1];
    for(int i=head[u];~i;i=e[i].nxt){
        int v=e[i].to;
        if(v!=fat) dfs(v,u);
    }
}
int lca(int u,int v){
    if(dep[u]<dep[v]) swap(u,v);
    for(int i=20;i>=0;i--)
        if(dep[u]-(1<<i)>=dep[v])
            u=fa[u][i];
    if(u==v) return u;
    for(int i=20;i>=0;i--)
        if(fa[u][i]!=fa[v][i])
            u=fa[u][i],v=fa[v][i];
    return fa[u][0];
}

//Segment Tree Merge
#define mid (pl+pr>>1)
int tot,root[N][2];
int tree[N*50],ls[N*50],rs[N*50];
void push_up(int x){
    if(rs[x]==0||tree[ls[x]]>=tree[rs[x]]) 
        tree[x]=tree[ls[x]];
    else tree[x]=tree[rs[x]];
}
void update(int &p,int pl,int pr,int pos,int v){
    if(!p) p=++tot;
    if(pl==pr) {
        tree[p]+=v;
        return ;
    }
    if(pos<=mid) update(ls[p],pl,mid,pos,v);
    else update(rs[p],mid+1,pr,pos,v);
    push_up(p);
}
int merge(int u,int v,int pl,int pr){
    if(!u||!v) return u+v;
    if(pl==pr){
        tree[u]+=tree[v];
        return u;
    }
    ls[u]=merge(ls[u],ls[v],pl,mid);
    rs[u]=merge(rs[u],rs[v],mid+1,pr);
    push_up(u);
    return u;
}
int query(int p,int pl,int pr,int pos){
    if(!p) return 0;
    if(pl==pr) return tree[p];
    if(pos<=mid) return query(ls[p],pl,mid,pos);
    else return query(rs[p],mid+1,pr,pos);
}

//Ciallo~
void calc(int u,int fat){
    for(int i=head[u];~i;i=e[i].nxt){
        int v=e[i].to;
        if(v==fat) continue;
        calc(v,u);
        root[u][0]=merge(root[u][0],root[v][0],1,n);
        root[u][1]=merge(root[u][1],root[v][1],-n,2*n);
    }
    if(dep[u]+w[u]>n) res[u]=0;
    else res[u]=query(root[u][0],1,n,dep[u]+w[u])+query(root[u][1],-n,2*n,dep[u]-w[u]);
}

signed main(){

    init();

    n=read(),m=read();
    for(int i=1;i<n;i++){
        int u=read(),v=read();
        add(u,v),add(v,u);
    }
    for(int i=1;i<=n;i++)
        w[i]=read();

    dfs(1,0);

    for(int i=1;i<=m;i++){
        int l=read(),r=read();
        int A=lca(l,r);
        update(root[l][0],1,n,dep[l],1);
        update(root[A][0],1,n,dep[l],-1);
        update(root[r][1],-n,2*n,2*dep[A]-dep[l],1);
        update(root[fa[A][0]][1],-n,2*n,2*dep[A]-dep[l],-1);
    }

    calc(1,0);

    for(int i=1;i<=n;i++)
        out(res[i]),putchar(' ');

    return 0;
}

|