当初听郭炜老师讲时不是很懂,几个月内每次复习树状数组必看的题

树的dfs序映射在树状数组上进行单点修改,区间查询。

/*
树状数组:
lowbit[i] = i&-i
C[i] = a[i-lowbit[i]+1]+...+a[i] 求和:
设sum[k] = a[1]+a[2]+...+a[k]
则a[i]+a[i+1]+...+a[j] = sum[j]-sum[i-1]
在树状数组上:sum[k] = C[n1]+C[n2]+...+C[k]
n1 = n2-lowbit[n2]... >0 更新:
如果a[i]更新了,则以下几项也要更新
C[n1], C[n2], ... C[nm]
n1 = i, n2 = n1+lowbit[n1].. nm<=N 建树:O(N)
C[k] = sum[k]-sum[k-lowbit[k]] poj3321
树状数组:单点更新
书上长满了苹果,每一个节点有长苹果和不长两种状态
操作1:改变树枝上有无苹果的状态
操作2:询问某一树枝节点以下的所有的苹果有多少 做一次dfs,几下每个节点的开始时间Start[i]和结束时间End[i]
对于i节点的所有子孙的开始时间和结束时间都应该位于Start[i]和End[i]之间
C[i]是树状数组节点对应的苹果数 然后用树状数组C统计Start[i]到End[i]之间的附加苹果总数
树状数组统计区间可以用Sum(End[i])-Sum(Start[i]-1)来计算
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define MAXN 220000
using namespace std;
int C[MAXN];
vector<vector<int> > G(MAXN/);//树
int Lowbit[MAXN];
int Start[MAXN];
int End[MAXN];
bool HasApple[MAXN/];
int nCount;
//dfs搜索出所有状态
void dfs(int v){
Start[v] = ++nCount;
for (int i = ; i != G[v].size(); i++)
dfs(G[v][i]);
End[v] = ++nCount;
}
//求1-p的和
int QuerySum(int p){
int nSum = ;
while(p > ){
nSum += C[p];
p -= Lowbit[p];
}
return nSum;
}
//修改节点p的值
void Modify(int p, int val){
while(p <= nCount){
C[p] += val;
p += Lowbit[p];
}
}
int main(){
int n;
scanf("%d", &n);
int x, y;
int i, j, k;
for (i = ; i < n-; i++){
int a, b;
scanf("%d%d", &a, &b);
G[a].push_back(b);
}
nCount = ;
dfs();//从根节点开始dfs //树状数组要处理的原石数组下标范围
for (i = ; i <= nCount; i++)
Lowbit[i] = i&(-i); for(i = ; i <= n; i++)
HasApple[i] = ; int m;
//建树求C数组,即树状数组的节点值
for(i = ; i <= nCount; i++)
C[i] = i-(i-Lowbit[i]);
//C[i] = Sum[i] - Sum[i-Lowbit[i]]; scanf("%d", &m);
for (int i = ; i < m; i++){
char cmd[];
int a;
scanf("%s%d", cmd, &a);
//改变某个节点上的苹果的状态
if (cmd[] == 'C') {
if(HasApple[a] == ){
Modify(Start[a], -);
Modify(End[a], -);
HasApple[a] = ;
}
else {
Modify(Start[a], );
Modify(End[a], );
HasApple[a] = ;
}
}
//查询某个节点上的苹果
else {
int t1 = QuerySum(Start[a]-);
int t2 = QuerySum(End[a]);
cout << (t2-t1)/ << endl;
}
}
}

poj3321 dfs序+树状数组单点更新 好题!的更多相关文章

  1. 【bzoj3881】[Coci2015]Divljak AC自动机+树链的并+DFS序+树状数组

    题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...

  2. 【bzoj3779】重组病毒 LCT+树上倍增+DFS序+树状数组区间修改区间查询

    题目描述 给出一棵n个节点的树,每一个节点开始有一个互不相同的颜色,初始根节点为1. 定义一次感染为:将指定的一个节点到根的链上的所有节点染成一种新的颜色,代价为这条链上不同颜色的数目. 现有m次操作 ...

  3. 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树

    题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...

  4. POJ 3321:Apple Tree + HDU 3887:Counting Offspring(DFS序+树状数组)

    http://poj.org/problem?id=3321 http://acm.hdu.edu.cn/showproblem.php?pid=3887 POJ 3321: 题意:给出一棵根节点为1 ...

  5. Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+ 树状数组或线段树

    C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...

  6. HDU 3887:Counting Offspring(DFS序+树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的. 思路:这题和那道苹果树是一样 ...

  7. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

  8. Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组

    C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...

  9. BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )

    一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状 ...

随机推荐

  1. shell提取文件后缀名,并判断其是否为特定字符串

    如果文件是 .css文件 或 .js文件,则进行处理. file=$1 if [ "${file##*.}"x = "css"x ]||[ "${fi ...

  2. Python基础【day03】:文件操作(七)

    零.本节内容 1.文件常用操作汇总 2.打开文件 3.操作文件 4.关闭文件 一.文件常用操作汇总 二.打开文件 1.普通打开模式 r,英文:read,只读模式(默认) w,英文:write,只写模式 ...

  3. 学习windows编程 day5 之 区域裁剪

    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRU ...

  4. form表单提交onclick和onsubmit

    onsubmit只能表单上使用,提交表单前会触发, onclick是按钮等控件使用, 用来触发点击事件. 在提交表单前,一般都会进行数据验证,可以选择在submit按钮上的onclick中验证,也可以 ...

  5. Java基础其他

    1. 二进制 进制就是进位制,常见的有二进制.十进制.十六进制等 在进制中,可用符号的数量称为基数,基数为n就称为n进制,逢n进一位: 二进制:0 1 十进制:0 1 2 3 4 5 6 7 8 9 ...

  6. C#在Win10与非Win10 Windows系统鼠标滚动编程的一点区别。

    C#在win10和非Win10上处理鼠标滚动有一些区别,建一个Form1,放置一个FlowLayoutPanel ,类型的Panel1 Panel.MouseWheel += PanelOnMouse ...

  7. 三、u-boot 的配置-mkconfig 脚本

    3.1 mkconfig 脚本 100ask24x0_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL ...

  8. Ubuntu 18.04换国内源 中科大源 阿里源 163源 清华源

    感觉还是18.4好用,所以最近装回了18,感觉现在18的兼容性也还可以了,深度学习的环境配置都没有问题,就是安装软件的时候有点慢,所以想要更新一下源. 第一步: 编辑/etc/apt/sources. ...

  9. js给<img>的src赋值

    用js原生方法:document.getElementById("imageId").src = "xxxx.jpg";用Jquery方法:$("#i ...

  10. Java 二进制I/O处理

    在Java中如何处理文本I/O 使用Scanner类读取文本数据,使用PrintWriter类写文本数据 例子: public class IO { public static void main(S ...