zoukankan      html  css  js  c++  java
  • Luogu P4116 Qtree3

    题目描述
    给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白
    
    有两种操作:
    
    0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑)
    
    1 v : 询问1到v的路径上的第一个黑点,若无,输出-1
    
    输入输出格式
    输入格式:
    第一行 N,Q,表示N个点和Q个操作
    
    第二行到第N行N-1条无向边
    
    再之后Q行,每行一个操作"0 i" 或者"1 v" (1 ≤ i, v ≤ N).
    
    输出格式:
    对每个1 v操作输出结果
    

    树剖搞搞就行了qwq

    对于线段树维护,若单点([q,q])为黑点,(ans[cur]=q)。否则为-1。

    关于上传,优先选择左儿子的非-1答案,若左儿子ans=-1,选择右儿子答案。

    记得输出的时候应该输出节点的初始编号,而不是树剖处理的新编号。新编号的时候标记一下即可。

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define MAXN 100233
    using namespace std;
    int n,m;
    int tot=0,cnt=0;
    struct qwq
    {
        int nex,to;
    }e[MAXN<<1];
    int h[MAXN];
    int fa[MAXN],top[MAXN],son[MAXN],dep[MAXN],siz[MAXN],id[MAXN];
    int w[MAXN]={};
    int ans[MAXN<<2];
    int nid[MAXN];
    inline void add(int x,int y)
    {
        e[++tot].to=y;
        e[tot].nex=h[x];
        h[x]=tot;
    }
    void dfs_fir(int x,int f,int dept)
    {
        dep[x]=dept;
        fa[x]=f;
        siz[x]=1;
        int maxn=-1;
        for (int i=h[x],y;i;i=e[i].nex)
        {
            y=e[i].to;
            if (y==f) continue;
            dfs_fir(y,x,dept+1);
            siz[x]+=siz[y];
            if (siz[y]>maxn)
            {
                son[x]=y;
                maxn=siz[y];
            }
        }
    }
    void dfs_sec(int x,int ft)
    {
        top[x]=ft;
        id[x]=++cnt;
        nid[cnt]=x;
        if (!son[x]) return;
        dfs_sec(son[x],ft);
        for (int i=h[x],y;i;i=e[i].nex)
        {
            y=e[i].to;
            if (y==son[x]||y==fa[x]) continue;
            dfs_sec(y,y);
        }
    }
    #define leftson cur<<1
    #define rightson cur<<1|1
    #define mid ((l+r)>>1)
    #define push_up if (ans[leftson]!=-1) { ans[cur]=ans[leftson]; return; } if (ans[rightson]!=-1) { ans[cur]=ans[rightson];return; } ans[cur]=-1
    void build(int cur,int l,int r)
    {
        if (l==r)
        {
            ans[cur]=-1;
            return;
        }
        build(leftson,l,mid);
        build(rightson,mid+1,r);
        push_up;
    }
    void change(int adn,int cur,int l,int r)
    {
        if (l==r)
        {
            if (ans[cur]!=-1)
            {
                ans[cur]=-1;
                return;
            }
            ans[cur]=l;
            return;
        }
        if (adn<=mid) change(adn,leftson,l,mid);
        else change(adn,rightson,mid+1,r);
        push_up;
    }
    int query(int ql,int qr,int cur,int l,int r)
    {
        if (ql<=l&&r<=qr)
        {
            return ans[cur];
        }
        if (ql<=mid)
        {
            int ans_a=query(ql,qr,leftson,l,mid);
            if (ans_a!=-1)
            {
                return ans_a;
            }
        }
        if (qr>mid) return query(ql,qr,rightson,mid+1,r);
        return -1;
    }
    int query_(int x,int y)
    {
        int ans_a,ans_b=-1;
        while (top[x]!=top[y])
        {
            if (dep[top[x]]<dep[top[y]]) swap(x,y);
            ans_a=query(id[top[x]],id[x],1,1,n);
    //		printf("::::::%d
    ",ans_a);
            if (ans_b==-1) 
            {
                ans_b=ans_a;
            }
            else if (ans_a!=-1)
            {
                ans_b=min(ans_a,ans_b);
            }
            x=fa[top[x]];
        }
        if (dep[x]>dep[y]) swap(x,y);
        ans_a=query(id[x],id[y],1,1,n);
    //	printf("::::::::::::%d
    ",ans_a);
        if (ans_b==-1) ans_b=ans_a;
        else if (ans_a!=-1) ans_b=min(ans_a,ans_b);
        return ans_b;
    }
    /*inline void DEBUG(int cur,int l,int r)
    {
        if (l==r)
        {
            printf("%d ",ans[cur]);
            return;
        }
        DEBUG(leftson,l,mid);
        DEBUG(rightson,mid+1,r);
    }*/
    int main()
    {
        scanf("%d%d",&n,&m);
        int x,y;
        for (int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        dfs_fir(1,1,1);
        dfs_sec(1,1);
        build(1,1,n);
        
        for (int i=1,answer;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            if (!x)
            {
                change(id[y],1,1,n);
    //			printf("#########################::%d
    
    ",query(1,5,1,1,n));
    //			DEBUG(1,1,n);
    //			printf("
    
    ");
                continue;
            }
            answer=query_(1,y);
            
            if (answer==-1) printf("-1
    ");
            else printf("%d
    ",nid[answer]);
        }
        return 0;
    }
    

    orz学长我真的不知道怎么就写到模拟赛原题了

    sto学长对不起虽然是原题我还是爆零了

  • 相关阅读:
    Redis相关操作指令
    Redis下载及安装(windows版)
    SpringBoot——登录验证码实现
    c++各种输入函数
    福昕阅读器关闭pdf文件后导致其被占用的处理办法
    面试之HTTP协议相关的问题
    在浏览器中输入URL后,执行的全部过程。会用到哪些协议?(一次完整的HTTP请求过程)
    Cookie与Session的原理
    Socket编程
    安全相关的问题、CSRF攻击、怎么确保数据传输中的安全性?
  • 原文地址:https://www.cnblogs.com/Kan-kiz/p/11158420.html
Copyright © 2011-2022 走看看