jzoj5221 [GDOI2018模拟7.10]A 主席树

Description


这里写图片描述
n 10 5

Solution


第一眼dsu on tree然后开一个桶,然后我写了主席树
结果这是最简单的题,直接每个点记录包含的最小、最大,和size比较一下就知道了

Code


#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)

const int N=200005;
const int E=200005;

struct edge {int y,next;} e[E];
struct treeNode {int l,r,sum;} t[N*51];

int root[N],pos[N],size[N],tot;
int ls[N],ans,edCnt;
int l[N],r[N],d[N],n;

bool v[N];

int read() {
    int x=0,v=1; char ch=getchar();
    for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
    for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
    return x*v;
}

void add_edge(int x,int y) {
    d[y]++;
    e[++edCnt]=(edge) {y,ls[x]}; ls[x]=edCnt;
}

void modify(int pre,int &now,int tl,int tr,int x) {
    t[now=++tot]=t[pre]; t[now].sum++;
    if (tl==tr) return ;
    int mid=(tl+tr)>>1;
    if (x<=mid) modify(t[pre].l,t[now].l,tl,mid,x);
    else modify(t[pre].r,t[now].r,mid+1,tr,x);
}

int query(int pre,int now,int tl,int tr,int l,int r) {
    if (tl==l&&tr==r) return t[now].sum-t[pre].sum;
    int mid=(tl+tr)>>1;
    if (r<=mid) return query(t[pre].l,t[now].l,tl,mid,l,r);
    if (l>mid) return query(t[pre].r,t[now].r,mid+1,tr,l,r);
    return query(t[pre].l,t[now].l,tl,mid,l,mid)+query(t[pre].r,t[now].r,mid+1,tr,mid+1,r);
}

void dfs1(int now) {
    l[now]=r[now]=now; pos[now]=++pos[0];
    modify(root[pos[0]-1],root[pos[0]],1,n,now);
    size[now]=1;
    for (int i=ls[now];i;i=e[i].next) {
        dfs1(e[i].y);
        l[now]=std:: min(l[e[i].y],l[now]);
        r[now]=std:: max(r[e[i].y],r[now]);
        size[now]+=size[e[i].y];
    }
}

void dfs2(int now) {
    for (int i=ls[now];i;i=e[i].next) {
        dfs2(e[i].y);
    }
    if (query(root[pos[now]-1],root[pos[now]+size[now]-1],1,n,l[now],r[now])==r[now]-l[now]+1) {
        v[now]=1; ans++;
    }
}

int main(void) {
    n=read(); int rt;
    rep(i,2,n) {
        int x=read(),y=read();
        add_edge(x,y);
    }
    rep(i,1,n) if (!d[i]) rt=i;
    dfs1(rt);
    dfs2(rt);
    printf("%d\n", ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/jpwang8/article/details/81132239