zoukankan      html  css  js  c++  java
  • 线段树(dfs序建树加区间更新和单点查询)

    题目链接:https://cn.vjudge.net/contest/66989#problem/J

    记录一下这道折磨了我一天的题,。。。。

    具体思路: 具体关系可通过dfs序建树,但是注意,在更新以及查询时的数和你dfs序建成的数是不一样的。因为你dfs序建成的树每个左右区间以及端点会发生不符合建树的条件。但是具体区间的更新还是可以通过新的树进行更新的,但是下属关系还是符合线段树的规则的,区间越大,也就是管理的人越多,也就是端点越往上。

    AC代码;

    #include<iostream>
    #include<string>
    #include<cstring>
    #include<iomanip>
    #include<map>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<set>
    #include<vector>
    #include<stdio.h>
    using namespace std;
    # define inf 0x3f3f3f3f
    # define maxn 500000+100
    # define ll long long
    # define lson l,m,rt<<1
    # define rson m+1,r,rt<<1|1
    vector<int>wakaka[maxn];
    int vis[maxn];
    int st[maxn];
    int ed[maxn];
    bool cover[maxn];
    int ans;
    int num;
    int a[maxn];
    void init()
    {
        memset(cover,0,sizeof(a));
        memset(vis,0,sizeof(vis));
        memset(st,0,sizeof(st));
        memset(ed,0,sizeof(ed));
        num=0;
    }
    void cal(int rt,int l,int r)
    {
        if(a[rt]==-1||l==r)return ;//必须先判断a[rt]是不是-1,如果是-1.则不能往下更新。
        a[rt<<1]=a[rt<<1|1]=a[rt];
        a[rt]=-1;
    }
    void dfs(int u)
    {
        st[u]=++num;
        int len=wakaka[u].size();
        for(int i=0; i<len; i++)
        {
            dfs(wakaka[u][i]);
        }
        ed[u]=num;
    }
    int query(int p,int l,int r,int rt)
    {
        if(l==r)//单点查询
        {
            return a[rt];
        }
        cal(rt,l,r);
        int m=(l+r)>>1;
        if(p<=m)query(p,lson);
        else if(p>m)query(p,rson);
    }
    void update(int col,int L,int R,int l,int r,int rt)
    {
        if(L<=l&&R>=r)
        {
            a[rt]=col;
            return ;
        }
        cal(rt,l,r);
        int m=(l+r)>>1;
        if(L<=m)update(col,L,R,lson);
        if(R>m)update(col,L,R,rson);
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        int t=0;
        while(T--)
        {
            int n,u,v;
            scanf("%d",&n);
            init();
            for(int i=1; i<=n; i++){
            wakaka[i].clear();
            }
            memset(a,-1,sizeof(a));
            for(int i=1; i<n; i++)
            {
                scanf("%d%d",&u,&v);
                wakaka[v].push_back(u);
                vis[u]=1;
            }
            for(int i=1; i<=n; i++)
            {
                if(!vis[i])
                {
                    dfs(i);
                    break;
                }
            }
            int m1;
            scanf("%d",&m1);
            char str[10];
            int t1,t2;
            printf("Case #%d:
    ",++t);
            while(m1--)
            {
                scanf("%s",str);
                if(str[0]=='C')
                {
                    scanf("%d",&t1);
                    printf("%d
    ",query(st[t1],1,n,1));//直接查询单点.
                }
                else if(str[0]=='T')
                {
                    scanf("%d%d",&t1,&t2);
                    update(t2,st[t1],ed[t1],1,n,1);//更新区间。
                }
            }
        }
        return 0;
    }
    
    
    
    
  • 相关阅读:
    “<”特殊符号写法
    js中,符合属性的js写法是讲下横杆去掉
    Windows 搭建WAMP+Mantis
    Windows server 2012 R2 服务器用户自动锁定
    对域用户设置为本地管理员权限
    windows 域控用户记住最后一次登录用户名
    redhat7.6 配置主从DNS
    redhat7.6 DNS配置正向解析
    redhat7.6 AIDE 系统文件完整性检查工具
    redhat7.6 httpd 匿名目录 目录加密 域名跳转
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262841.html
Copyright © 2011-2022 走看看