线段树合并求DEBUG

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

qwq2519 @ 2020-10-19 21:18:52

#include<bits/stdc++.h>
#define rep(i,j,k) for(register int i(j);i<=k;++i)
#define drp(i,j,k) for(register int i(j);i>=k;--i)
using namespace std;
inline void read(int &x)
{
    x=0;
    register char ch=getchar();
    int w=0;
    while(ch<'0'||ch>'9')
        {
            w|=ch=='-';
            ch=getchar();
        }
    while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-48;
            ch=getchar();
        }
    w?x=~(x-1):x;
}
const int N=300709;
int n,m;
int apper[N];
int start[N],end[N];
int ans[N];

struct graph
{
    int head[N<<1],tot,ver[N<<1],next[N<<1];
    inline void add(int a,int b)
    {
        ver[++tot]=b;
        next[tot]=head[a];
        head[a]=tot;
    }
} G;
int dfn[N],fa[N];
int size[N],son[N];
int top[N],depth[N];
int num;
inline void dfs1(int x,int fath)
{
    size[x]=1;
    depth[x]=depth[fath]+1;
    fa[x]=fath;
    int maxson=-1;
    for(register int i(G.head[x]); i; i=G.next[i])
        {
            int y=G.ver[i];
            if(y==fath) continue;
            dfs1(y,x);
            size[x]+=size[y];
            if(size[y]>maxson) maxson=size[y],son[x]=y;
        }
}
inline void dfs2(int x,int topf)
{
    top[x]=topf;
    dfn[x]=++num;
    if(!son[x]) return;
    dfs2(son[x],topf);
    for(register int i(G.head[x]); i; i=G.next[i])
        {
            int y(G.ver[i]);
            if(dfn[y]) continue;
            dfs2(y,y);
        }
}
inline int lca(int x,int y)
{
    while(top[x]!=top[y])
    {
        if(depth[top[x]]<depth[top[y]]) swap(x,y);
        x=fa[top[x]];
    }
    return depth[x]<depth[y] ? x: y;
}
int root1[N],root2[N];
int date[N<<5],cnt,lc[N<<5],rc[N<<5];
inline void change(int &p,int L,int R,int x,int v)
{
    if(!p) p=++cnt;
    if(L==R)
    {
        date[p]+=v;
        return;
     }
     int mid((L+R)>>1); 
    if(x<=mid) change(lc[p],L,mid,x,v);
    else change(rc[p],mid+1,R,x,v);
}

inline int query(int p,int L,int R,int x)
{
    if(!p) return 0;
    if(L==R) return date[p];
    int mid((L+R)>>1); 
    if(x<=mid) return query(lc[p],L,mid,x);
    else return(rc[p],mid+1,R,x);
}

inline int merge(int a,int b,int l,int r)
{
    if(a==0||b==0) return a+b;
    if(l==r){
        date[a]+=date[b];
        return a;
    }
    int mid((l+r)>>1);
    lc[a]=merge(lc[a],lc[b],l,mid);
    rc[a]=merge(rc[a],rc[b],mid+1,r);
    return a;
}
inline void calc(int x,int fath)
{
    for(register int i(G.head[x]);i;i=G.next[i])
    {
        int y(G.ver[i]);
        if(y==fath) continue;
        calc(y,x);
        root1[x]=merge(root1[x],root1[y],1,n*2);
        root2[x]=merge(root2[x],root2[y],1,n*2);
    }
    ans[x]=query(root1[x],1,n*2,depth[x]+apper[x])+query(root2[x],1,n*2,n+apper[x]-depth[x]);
}

int main()
{
//  freopen("running.in","r",stdin);
//  freopen("running.out","w",stdout);
    read(n);
    read(m);
    int u,v;
    rep(i,1,n-1)
    {
        read(u);
        read(v);
        G.add(u,v);
        G.add(v,u);
    }
    dfs1(1,0);
    dfs2(1,1);
    rep(i,1,n) read(apper[i]);
    rep(i,1,m)
    {
        read(u);read(v);
        int g=lca(u,v);
        change(root1[u],1,n*2,depth[u],1);
        change(root1[g],1,n*2,depth[u],-1);
        change(root2[v],1,n*2,n+depth[u]-depth[g]*2,1);
        change(root2[fa[g]],1,n*2,n+depth[u]-depth[g]*2,-1);
    }
    calc(1,1);
    rep(i,1,n-1)
     printf("%d ",ans[i]);
    printf("%d",ans[n]);

    return 0;
}

RT、。。。样例过不了


by qwq2519 @ 2020-10-19 21:42:07

我想我找到了。。。。。

问题已解决,羞于启齿


|