• POJ 3321 Apple Tree(树状数组模板)


    原题链接:POJ3321

    解析:这题我按照郭炜老师的讲义来练习树状数组的模板,但是也遇到了一些问题:

    1. 如果对一些图或树来用树状数组解题,就需要给他每个节点一个从1到nCount的编号,因为树状数组只能从1~n求和
    2. 刚开始我用vector<int> G[maxn]来存图,但是超时了,改用vector<vector<int> > G(maxn)就过了,可见以后尽量用第二种方法来存图
    3. lowbit[]数组可以预处理,节约一点时间

    代码实例:

    #include<iostream>
    #include<cstdio>
    #include<vector>
    using namespace std;
    const int maxn = 220000;
    vector<vector<int> > G(maxn);//存边 
    int Start[maxn],End[maxn];//Start和End相当于存每个节点id 
    int lowbit[maxn];//二进制最右面的1 
    int C[maxn];//C[i]表示从A[i-lowbit[i]+1]到A[i] 的和,本题A[i]都为1 
    int nCount = 0;
    int HasApple[maxn];//当前节点是否有苹果 
    void DFS(int v){
    	Start[v] = ++nCount;
    	for(int i = 0;i < G[v].size();i++)
    		DFS(G[v][i]);
    	End[v] = ++nCount;
    }
    int q_sum(int p){
    	int nSum = 0;
    	while(p > 0){
    		nSum += C[p];//由于每段和都存在对应的C[i]中,故每次减去lowbit[i]来去下一段的C 
    		p -= lowbit[p];
    	}
    	return nSum;
    }
    void Modify(int p,int val){
    	while(p <= nCount){
    		C[p] += val;
    		p += lowbit[p];
    	}
    }
    int main()
    {
    	int n;
    	scanf("%d",&n);
    	int u,v;
    	for(int i = 0;i < n-1;i++){
    		scanf("%d%d",&u,&v);
    		G[u].push_back(v);
    	}
    	DFS(1);
    	for(int i = 1;i <= nCount;i++)
    		lowbit[i] = i&-i;
    	for(int i = 1;i <= n;i++)
    		HasApple[i] = 1;
    	for(int i = 1;i <= nCount;i++)
    		C[i] = i - (i - lowbit[i]);
    	int m;
    	scanf("%d",&m);
    	for(int i = 0;i < m;i++){
    		char cmd[10];
    		int p;
    		scanf("%s %d",cmd,&p);
    		if(cmd[0] == 'C'){
    			if(HasApple[p]){
    				Modify(Start[p],-1);
    				Modify(End[p],-1);
    				HasApple[p] = 0;
    			}else{
    				Modify(Start[p],1);
    				Modify(End[p],1);
    				HasApple[p] = 1;
    			}
    		}else {	
    			int t1 = q_sum(End[p]);
    			int t2 = q_sum(Start[p]-1);
    			printf("%d
    ",(t1-t2)/2);//所求部分被计算了两次 
    		}
    	}
    	return 0;
    } 
  • 相关阅读:
    yun rpm
    Codeforces Round #375 (Div. 2) D. Lakes in Berland (DFS或并查集)
    51nod 1276 1276 岛屿的数量 (很好玩的题目
    玄学C语言之scanf,printf
    51nod 算法马拉松17 解题报告 以后不能赛中写题解(查逐梦者抄袭本人代码...
    51Nod 1007 正整数分组 -简单DP
    算法马拉松13 A-E解题报告
    十五天集训_
    贴一发STL源码
    省赛反思以及未来提高计划
  • 原文地址:https://www.cnblogs.com/long98/p/10352190.html
Copyright © 2020-2023  润新知