• POJ 3321 Apple Tree DFS序+fenwick


    题目大意:有一颗长满苹果的苹果树,有两个操作。

    1.询问以一个点为根的子树中有多少个苹果。

    2.看看一个点有没有苹果,假设没有苹果。那么那里就立即长出一个苹果(= =!);否则就把那个苹果摘下来。


    思路:进行一次深搜,将每一个节点最開始出现的时间和最后出现的时间记在一个数组里,那么这两点之间的点就是它以及它的子树的二倍,然后就用树状数组来维护区间和即可了。


    CODE:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define MAX 200010
    using namespace std;
    
    pair<int,int> pos[MAX];
    
    int points,asks;
    int head[MAX],total;
    int next[MAX << 1],aim[MAX << 1];
    int cnt;
    bool src[MAX];
    int fenwick[MAX];
    
    char c[10];
    
    inline void Add(int x,int y);
    void DFS(int x,int last);
    
    inline void Fix(int x,int c);
    inline int GetSum(int x);
    
    int main()
    {
    	cin >> points;
    	for(int x,y,i = 1;i < points; ++i) {
    		scanf("%d%d",&x,&y);
    		Add(x,y),Add(y,x);
    	}
    	DFS(1,-1);
    	memset(src,true,sizeof(src));
    	for(int i = 1;i <= points; ++i)
    		Fix(pos[i].first,1),Fix(pos[i].second,1);
    	cin >> asks;
    	for(int x,i = 1;i <= asks; ++i) {
    		scanf("%s%d",c,&x);
    		if(c[0] == 'Q')
    			printf("%d
    ",(GetSum(pos[x].second) - GetSum(pos[x].first - 1)) >> 1);
    		else {
    			if(src[x]) {
    				Fix(pos[x].first,-1);
    				Fix(pos[x].second,-1);
    				src[x] = false;
    			}
    			else {
    				Fix(pos[x].first,1);
    				Fix(pos[x].second,1);
    				src[x] = true;
    			}
    		}
    	}
    	return 0;
    }
    
    inline void Add(int x,int y)
    {
    	next[++total] = head[x];
    	aim[total] = y;
    	head[x] = total;
    }
    
    void DFS(int x,int last)
    {
    	pos[x].first = ++cnt;
    	for(int i = head[x];i;i = next[i]) {
    		if(aim[i] == last)	continue;
    		DFS(aim[i],x);
    	}
    	pos[x].second = ++cnt;
    }
    
    inline void Fix(int x,int c)
    {
    	for(;x <= (points << 1);x += x&-x)
    		fenwick[x] += c;
    }
    
    inline int GetSum(int x)
    {
    	int re = 0;
    	for(;x;x -= x&-x)
    		re += fenwick[x];
    	return re;
    }


  • 相关阅读:
    24. Swap Nodes in Pairs(M);25. Reverse Nodes in k-Group(H)
    61. Rotate List(M);19. Remove Nth Node From End of List(M)
    素数筛选法(prime seive)
    哈夫曼树;二叉树;二叉排序树(BST)
    sort与qsort的区别与联系
    贪心算法
    First non-repeating character in a stream
    transform
    C++11 & C++14 & C++17新特性
    开个玩笑
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5183643.html
Copyright © 2020-2023  润新知