zoukankan      html  css  js  c++  java
  • POJ 3321 Apple Tree(树状数组)

    点我看题目 

    题意 : 大概是说一颗树有n个分岔,然后给你n-1对关系,标明分岔u和分岔v是有边连着的,然后给你两个指令,让你在Q出现的时候按照要求输出。

    思路 :典型的树状数组。但是因为没有弄好数组,所以要用DFS先映射一下,好吧我承认我说不下去了,六级没过,CF又掉了100多分,脑子完全不转转了。。。。。。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    
    using namespace std;
    
    const int maxn = 500004 ;
    int head[maxn],start[maxn] ,num[maxn],data[maxn];
    int m,n,cnt ,cntt;
    bool vis[maxn] ;
    
    struct node
    {
        int l,r ;
        int next ;
    }Node[maxn] ;
    
    void addegde(int u,int v)
    {
        Node[cnt].l = u ;
        Node[cnt].r = v ;
        Node[cnt].next = head[u] ;
        head[u] = cnt++ ;
    }
    
    void dfs(int u)
    {
        start[u] = ++ cntt ;
        vis[u] = true ;
        for(int i = head[u] ; i+1 ; i = Node[i].next)
        {
            int v = Node[i].r ;
            if(!vis[v])
            dfs(v) ;
        }
        num[u] = cntt ;
    }
    int lowbit(int x)
    {
        return x&(-x) ;
    }
    int sum(int i )
    {
        int summ = 0 ;
        while(i > 0)
        {
            summ += data[i] ;
            i -= lowbit(i) ;
        }
        return summ ;
    }
    
    void update(int i,int val)
    {
        while(i <= n)
        {
            data[i] += val ;
            i += lowbit(i) ;
        }
    }
    
    int main()
    {
        while(~scanf("%d",&n))
        {
            cnt = cntt = 0 ;
            memset(head,-1,sizeof(head)) ;
            memset(num,0,sizeof(num)) ;
            memset(start,0,sizeof(start)) ;
            memset(data,0,sizeof(data)) ;
            memset(vis,false,sizeof(vis)) ;
            int x,y ;
            for(int i = 1 ; i <= n-1 ; i++ )
            {
                scanf("%d %d",&x,&y) ;
                addegde(x,y) ;
            }
            dfs(1) ;
            for(int i = 1 ; i <= n ; i++)
                update(i,1) ;
            scanf("%d",&m) ;
            getchar() ;
            for(int j = 1 ; j <= m ; j++)
            {
                char ch ;
                scanf("%c",&ch) ;
                if(ch == 'Q')
                {
                    scanf("%d",&x) ;
                    printf("%d
    ",sum(num[x])-sum(start[x]-1)) ;
                }
                else if(ch == 'C')
                {
                    scanf("%d",&x) ;
                    if(sum(start[x])-sum(start[x]-1))
                        update(start[x],-1) ;
                    else
                        update(start[x],1) ;
                }
                getchar() ;
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    大整数乘除法
    java大神进阶之路
    自定义Swap
    指针基础详解
    已知前序中序求后序(转载)
    杭电1003_Max Sum
    回溯法求解迷宫问题
    linux下安装QQ等EXE文件
    java工程中使用freemarker例子
    maven自动部署到tomcat的问题
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3558904.html
Copyright © 2011-2022 走看看