• poj 3321(带时间戳 + 区间统计)


    题目描述:

    给定一颗树,求某个节点的子树的val值之和

    可以用树的前序遍历给每一个节点编号,从而可以确定一个节点的子树的范围,这样就可以进行直接在区间上进行统计了。

    vector < int > Map[maxN]写成typedef vector <int> INT; vector <INT> Map(maxN);就不超时了。

    线段树

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #define LL long long
    using namespace std;
    //线段树
    //区间每点增值,求区间和
    const int maxN = 110000;
    struct node
    {
        int lt, rt;
        int val;
    }tree[4*maxN];
    
    
    //向上更新
    void pushUp(int id)
    {
        tree[id].val = tree[id<<1].val + tree[id<<1|1].val;
    }
    
    //建立线段树
    void build(int lt, int rt, int id)
    {
        tree[id].lt = lt;
        tree[id].rt = rt;
       // tree[id].val = 1;//每段的初值,根据题目要求
        if (lt == rt)
        {
            tree[id].val=1;
            return;
        }
        int mid = (lt+rt)>>1;
        build(lt, mid, id<<1);
        build(mid+1, rt, id<<1|1);
        pushUp(id);
    }
    
    //增加区间内每个点固定的值
    void add(int lt, int rt, int id)
    {
        if (lt <= tree[id].lt && rt >= tree[id].rt)
        {
            if(tree[id].val==1)
                tree[id].val=0;
            else
                tree[id].val=1;
            return;
        }
        int mid = (tree[id].lt+tree[id].rt)>>1;
        if (lt <= mid)
            add(lt, rt, id<<1);
        if (rt > mid)
            add(lt, rt, id<<1|1);
        pushUp(id);
    }
    
    //查询某段区间内的和
    int query(int lt, int rt, int id)
    {
        if (lt <= tree[id].lt && rt >= tree[id].rt)
            return tree[id].val;
        int mid = (tree[id].lt+tree[id].rt)>>1;
        int ans = 0;
        if (lt <= mid)
            ans += query(lt, rt, id<<1);
        if (rt > mid)
            ans += query(lt, rt, id<<1|1);
        return ans;
    }
    
    
    struct NODE
    {
        int cnt,l,r;
    }a[maxN];
    typedef vector<int > INT;
    vector<INT > Map(maxN);
    int vis[maxN];
    int number;
    void dfs(int fa)
    {
        for(int i=0;i<Map[fa].size();i++)
        {
            int son=Map[fa][i];
            if(vis[son]==0)
            {
                a[son].cnt=++number;
                a[son].l= number;
                vis[son]=1;
                dfs(son);
                a[son].r=number;
            }
        }
    }
    void init()
    {
        for(int i=0;i<maxN;i++)
            Map[i].clear();
    }
    int main()
    {
       // freopen("test.txt","r",stdin);
        int n,m;
        while(~scanf("%d",&n))
        {
            init();
            for(int i=1;i<=n-1;i++)
            {
                int from,to;
                scanf("%d%d",&from,&to);
                Map[from].push_back(to);
                Map[to].push_back(from);
            }
            number=1;
            memset(vis,0,sizeof(vis));
            a[1].cnt=1;
            a[1].l=1;
            vis[1]=1;
    
            dfs(1);
    
            a[1].r=number;
    
            build(a[1].l,a[1].r,1);
            //for(int i=1;i<=9;i++)
            // printf("%d %d %d
    ",a[i].cnt,a[i].l,a[i].r);
            int M;
            scanf("%d",&M);
            char str[5];   int id;
            while(M--)
            {
                scanf("%s%d",str,&id);
                //printf("%s
    ",str);
                if(str[0]=='Q')
                {
                    printf("%d
    ",query(a[id].l,a[id].r,1) );
                }
                if(str[0]=='C')
                {
                    add(a[id].cnt,a[id].cnt,1);
                }
            }
        }
        return 0;
    }

    树状数组

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #define LL long long
    using namespace std;
    const int maxN = 110000;
    int n;
    //树状数组
    int C[maxN],A[maxN];
    int lowbit(int x)
    {
        return x&(-x);
    }
    int sum(int x)
    {
        int ret=0;
        while(x>0)
        {
            ret+=C[x]; x-=lowbit(x);
        }
        return ret;
    }
    void update(int x,int pls)
    {
        int d;
        if(pls==0)
        {
            if(A[x]==0)
            d=1;
            if(A[x]==1)
            d=-1;
        }
        else
            d=1;
        A[x]+=d;
        while(x<=n)
        {
            C[x]+=d; x+=lowbit(x);
        }
    }
    struct NODE
    {
        int cnt,l,r;
    }a[maxN];
    typedef vector<int>  INT;
    vector < INT >   Map(maxN);
    int vis[maxN];
    int number;
    void dfs(int fa)
    {
        for(int i=0;i<Map[fa].size();i++)
        {
            int son=Map[fa][i];
            if(vis[son]==0)
            {
                a[son].cnt=++number;
                a[son].l= number;
                vis[son]=1;
                dfs(son);
                a[son].r=number;
            }
        }
    }
    void init()
    {
        for(int i=0;i<maxN;i++)
            Map[i].clear();
    }
    int main()
    {
        //freopen("test.txt","r",stdin);
        while(~scanf("%d",&n))
        {
            init();
            for(int i=1;i<=n-1;i++)
            {
                int from,to;
                scanf("%d%d",&from,&to);
                Map[from].push_back(to);
                Map[to].push_back(from);
            }
            number=1;
            memset(vis,0,sizeof(vis));
            a[1].cnt=1;
            a[1].l=1;
            vis[1]=1;
    
            dfs(1);
    
            a[1].r=number;
            memset(C,0,sizeof(C));
            memset(A,0,sizeof(A));
            for(int i=1;i<=n;i++)
                update(i,1);
            int M;
            scanf("%d",&M);
            char str[5];   int id;
            while(M--)
            {
                scanf("%s%d",str,&id);
                if(str[0]=='Q')
                {
                    printf("%d
    ",sum(a[id].r) -sum(a[id].l-1) );
                }
                if(str[0]=='C')
                {
                     update(a[id].cnt,0);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    洛谷 P2607 [ZJOI2008]骑士(基环树、树形dp)
    洛谷 P1453 城市环路(基环树,树形dp)
    基环树学习笔记 & CF711D Directed Roads
    centos7 系统安全加固方案
    来自后端的突袭? --开包即食的教程带你浅尝最新开源的C# Web引擎 Blazor
    作为一个C#程序员, 你应该上手Kotlin
    python中类和self讲解
    Mysql 存储引擎中InnoDB与Myisam的主要区别
    Apache和Nginx的区别
    PHP超全局变量
  • 原文地址:https://www.cnblogs.com/xianbin7/p/4868213.html
Copyright © 2020-2023  润新知