十一届院赛 I题 我要10个G

来源:互联网 发布:手机版迅雷网络异常 编辑:程序博客网 时间:2024/06/17 18:16
题目给出n个点,只有n-1条边,而且都是连通的,那么就可以得出是一棵树。
那就变成了裸的树剖。
套模板,完事。
#include<stdio.h>#include<algorithm>#include<string>#include<string.h>#include<queue>#include<vector>#include<stack>#include<math.h>#include<map>#include<iostream>using namespace std;#define maxn 300050struct edge{    int en,next;}E[maxn*2];struct node{    int l;    int r;    int smin;}tree[maxn*8];int a[maxn];int dep[maxn];  //节点深度int fa[maxn];   //节点父亲int siz[maxn];  //以V为跟的节点数目int son[maxn];  //V节点的重儿子int p[maxn],fp[maxn];  //p[v],节点v在线段树中的位置,fp[v]是p的反向映射int top[maxn];      // v节点的重链的顶端int head[maxn],cnt,pos,n,q;  //邻接表void addedge(int st,int en){    E[cnt].en=en;    E[cnt].next=head[st];    head[st]=cnt;    cnt++;}void inti(){    cnt=0;pos=0;    memset(son,-1,sizeof(son));    memset(a,0,sizeof(a));    memset(dep,0,sizeof(dep));    memset(fa,0,sizeof(fa));    memset(p,0,sizeof(p));    memset(siz,0,sizeof(siz));    memset(head,-1,sizeof(head));}void dfs1(int u,int f,int d){    dep[u]=d;    fa[u]=f;    siz[u]=1;    for(int i=head[u];i!=-1;i=E[i].next)    {        int v=E[i].en;        if(v!=f)        {            dfs1(v,u,d+1);            siz[u] += siz[v];            if(son[u]==-1||siz[v]>siz[son[u]])                son[u]=v;        }    }}void pushup(int id){    tree[id].smin=min(tree[id*2].smin,tree[id*2+1].smin);}void build(int id,int l,int r){    tree[id].l=l;    tree[id].r=r;    if(l==r)    {        tree[id].smin=1;        return ;    }    int mid=(l+r)/2;    build(id*2,l,mid);    build(id*2+1,mid+1,r);    pushup(id);}void update(int id,int x,int v){    int l=tree[id].l;    int r=tree[id].r;    int mid=(l+r)/2;    if(l==r)    {        tree[id].smin=v;        return ;    }    if(l<=x&&x<=mid)        update(id*2,x,v);    else if(mid<x&&x<=r)        update(id*2+1,x,v);    pushup(id);}int querymin(int id,int x,int y){    int l=tree[id].l;    int r=tree[id].r;    int mid=(l+r)/2;    if(x<=l&&r<=y)        return tree[id].smin;    if(y<l||x>r)        return 1e9;    return min(querymin(id*2,x,y),querymin(id*2+1,x,y));}void getpos(int u,int sp){    top[u]=sp;    p[u]=pos++;    fp[p[u]]=u;    if(son[u]==-1)        return ;    getpos(son[u],sp);    for(int i=head[u];i!=-1;i=E[i].next)    {        int v=E[i].en;        if(v!=son[u]&&v!=fa[u])            getpos(v,v);    }}int findmin(int u,int v){    int f1=top[u],f2=top[v];    int ret=1e9;    while(f1!=f2)    {        if(dep[f1]<dep[f2])        {            swap(f1,f2);            swap(u,v);        }        ret=min(ret,querymin(1,p[f1],p[u]));        u=fa[f1];        f1=top[u];    }    if(dep[u]>dep[v])        swap(u,v);    return min(ret,querymin(1,p[u],p[v]));}int main(){    while(scanf("%d%d",&n,&q)!=EOF)    {        inti();        for(int i=1;i<n;i++)        {            int x,y;            scanf("%d%d",&x,&y);            addedge(x,y);            addedge(y,x);        }        dfs1(1,0,0);        getpos(1,1);        build(1,0,pos-1);        while(q--)        {            int s,x,y;            scanf("%d",&s);            if(s==1)            {                scanf("%d%d",&x,&y);                int ans=findmin(x,y);                if(ans==1)                    printf("YES\n");                else                    printf("NO\n");            }            else if(s==2)            {                scanf("%d",&x);                update(1,p[x],1);            }            else            {                scanf("%d",&x);                update(1,p[x],0);            }        }    }return 0;}

0 0
原创粉丝点击