AC

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

_ZZH @ 2016-12-24 19:46:01

#include<cstdio>
using namespace std;
struct edge{int v,nxt;};//一个二元组类型,作为链表节点使用
typedef edge zu[600600];//链表数组
typedef int arr[600600];
int n,m,tot,u,v;
arr s,t,fa,pos,fst,qf,ans,lc,w,dep,bj[2],bl[2],cnt[2];
//s,t为每个跑步者的起点,终点,lc为s,t最近公共祖先
//fa tarjan最近公共祖先中的并查集
zu le,q,lian[2],ll[2];//几个链表,le存图,q离线询问(tarjan)
bool vis[300300];
inline int getf(int x){return (x==fa[x]?x:fa[x]=getf(fa[x]));}//并查集求父亲操作
inline void gl(int f,int &s,zu z){z[++tot]=(edge){f,s},s=tot;}//挂链表
inline int lca(int u,int d){
    vis[u]=1;
    dep[u]=d;
    fa[u]=u;
    for(int now=fst[u];now;now=le[now].nxt)if(!vis[le[now].v])fa[lca(le[now].v,d+1)]=u;
    for(int now=qf[u];now;now=q[now].nxt)if(vis[q[now].v])lc[now>>1]=getf(q[now].v);
    return u;
}
//tarjan过程
inline void make(int u,int a,int b){
    vis[u]=0;
    int v;
    for(int now=fst[u];now;now=le[now].nxt)if(vis[v=le[now].v])
        make(v,cnt[0][w[v]+dep[v]+300000],cnt[1][w[v]-dep[v]+300000]);
    for(int now=qf[u];now;now=q[now].nxt)
        cnt[!(now&1)][dep[s[now>>1]]-2*(!(now&1)?dep[lc[now>>1]]:0)+300000]++;
    //!(now&1)代表now为偶数,若now为偶数,q[now]挂的是t[now/2],否则是s[now/2],所以式子会有所不同
    ans[u]=cnt[0][w[u]+dep[u]+300000]+cnt[1][w[u]-dep[u]+300000]-a-b;
    for(int now=bj[0][u];now;now=lian[0][now].nxt){
        if(lian[0][now].v==w[u]+dep[u])ans[u]--;
        cnt[0][lian[0][now].v+300000]--;
    }
    for(int now=bj[1][u];now;now=lian[1][now].nxt)cnt[1][lian[1][now].v+300000]--;
}
//dfs求答案过程
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<n;i++){
        scanf("%d%d",&u,&v);
        gl(v,fst[u],le);
        gl(u,fst[v],le);
    }
    for(int i=1;i<=n;i++)scanf("%d",&w[i]);
    tot=1;
    for(int i=1;i<=m;i++){
        scanf("%d%d",&s[i],&t[i]);
        gl(s[i],qf[t[i]],q);
        gl(t[i],qf[s[i]],q);
    }
    lca(1,0);
    tot=0;
    for(int i=1;i<=m;i++){
        gl(dep[s[i]],bj[0][lc[i]],lian[0]);
        --tot,gl(dep[s[i]]-2*dep[lc[i]],bj[1][lc[i]],lian[1]);
    }
    make(1,0,0);
    for(int i=1;i<=n;i++)printf("%d ",ans[i]);
    return 0;
}

by _ZZH @ 2016-12-24 19:46:37

如果你们提交正确之后请留言


by 1124828077ccj @ 2016-12-30 20:56:21

@jiaxuan_2016 你要写就写题解去,不要写在这里,你不觉得这是炫耀吗


by luaddict @ 2017-01-07 11:42:59

@2016陈常杰 你怎么就觉得这是炫耀?别人注释照样写得清清楚楚。只是换个地方发,就变成炫耀了?


by 1124828077ccj @ 2017-01-07 11:45:22

@SilverWolf 不,就算这不是炫耀,但是讨论也不是该发正确代码的地方,如果是,那么题解是干嘛的


by _ZZH @ 2017-01-09 10:01:23

闭肛


by pb0207 @ 2017-04-21 08:47:44

@jiaxuan_2016 题主居然在骂人啊 虽然老坟了,但我还是

puts("BS");吧

其实我也举得在炫耀


by Taduro @ 2018-08-26 12:09:14

题主居然在骂人啊 虽然老坟了,但我还是 puts("BS");吧

其实我也觉得在炫耀


by Hooch @ 2021-10-14 18:17:05

考古


|