poj_1190 树状数组
题目大意
给定一个S*S的矩形,该矩形由S*S个1x1的单元格构成,每个单元格内可以放一个整数,每次有如下可能操作:
(1)改变某个单位单元格中的数的大小
(2)查询由若干个连续单元格构成的X*Y的大小的矩形内所有数的总和
题目分析
典型的区间操作,而且是单点更新,区间查询。因此使用树状数组,不过应该使用二维树状数组。二维树状数组和一维其实没什么区别。。。。
另:用线段树也做了一份,但是超时,果然树状数组在效率上还是略胜线段树的。下面给出树状数组的AC代码和线段树的TLE代码。
实现(c++)
1.树状数组
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#define MAX_SQUARE_SIZE 1025
#define MAX(a, b) a>b? a:b
#define MIN(a, b) a <b? a:b
int gLowBit[MAX_SQUARE_SIZE];
int gC[MAX_SQUARE_SIZE][MAX_SQUARE_SIZE]; void InitLowBit(int n){
for (int i = 1; i <= n; i++){
gLowBit[i] = i&(-i);
}
} void InitSequence(int n){
memset(gC, 0, sizeof(gC));
} void Update(int x, int y, int n, int add){
int tmp_y = y;
while (x <= n){
y = tmp_y;
while (y <= n){
gC[x][y] += add;
y += gLowBit[y];
}
x += gLowBit[x];
}
}
int Query1(int x, int y){
int tmp_y = y, result = 0;
while (x > 0){
y = tmp_y;
while (y > 0){
result += gC[x][y];
y -= gLowBit[y];
}
x -= gLowBit[x];
}
return result;
} int Query(int left, int right, int bottom, int top){
int r_t = Query1(right, top);
int l_t = Query1(left - 1, top);
int r_b = Query1(right, bottom - 1);
int l_b = Query1(left - 1, bottom - 1); //注意在查询的时候,需要计算的矩形的边界弄清楚 [i , ... j] = sum(j) = sum(i - 1)
return (r_t + l_b - l_t - r_b);
}
int main(){
int ins;
int S, X, Y, A, L, B, R, T;
scanf("%d %d", &ins, &S);
InitLowBit(S);
InitSequence(S);
while (scanf("%d", &ins)){
if (ins == 3){
break;
}
if (ins == 1){
scanf("%d %d %d", &X, &Y, &A);
Update(X+1, Y+1, S, A);
}
else if (ins == 2){
scanf("%d %d %d %d", &L, &B, &R, &T);
int result = Query(L+1, R+1, B+1, T+1);
printf("%d\n", result);
}
}
return 0;
}
2.线段树
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define MAX_SQUARE_SIZE 1025
#define MAX_NODE_NUM MAX_SQUARE_SIZE*4
#define MAX(a, b) a>b? a:b
#define MIN(a, b) a <b? a:b
struct Node{
short left;
short right;
short top;
short bottom;
int sum_phones;
short h_mid(){
return (left + right) >> 1;
}
short v_mid(){
return (top + bottom) >> 1;
}
};
Node gNodes[MAX_NODE_NUM][MAX_NODE_NUM];
void BuildTree(int h_index, int v_index, short left, short right, short bottom, short top){
gNodes[h_index][v_index].left = left;
gNodes[h_index][v_index].right = right;
gNodes[h_index][v_index].top = top;
gNodes[h_index][v_index].bottom = bottom;
gNodes[h_index][v_index].sum_phones = 0;
if (left == right || top == bottom){
return;
}
int left_child = 2 * h_index + 1, right_child = 2 * h_index + 2;
int up_child = 2 * v_index + 1, down_child = 2 * v_index + 2;
short h_mid = (left + right) >> 1, v_mid = (top + bottom) >> 1;
BuildTree(left_child, down_child, left, h_mid, bottom, v_mid);
BuildTree(right_child, down_child, h_mid + 1, right, bottom, v_mid);
BuildTree(left_child, up_child, left, h_mid, v_mid + 1, top);
BuildTree(right_child, up_child, h_mid + 1, right, v_mid + 1, top);
} void Update(int h_index, int v_index, short left, short right, short bottom, short top, int add){
if (gNodes[h_index][v_index].left == gNodes[h_index][v_index].right){ //arrive to the point
gNodes[h_index][v_index].sum_phones += add;
return;
}
if (left > gNodes[h_index][v_index].right || right < gNodes[h_index][v_index].left
|| top < gNodes[h_index][v_index].bottom || bottom > gNodes[h_index][v_index].top){
return;
}
if (left > right || bottom > top){
return;
}
int left_child = 2 * h_index + 1, right_child = 2 * h_index + 2;
int up_child = 2 * v_index + 1, down_child = 2 * v_index + 2;
short h_mid = gNodes[h_index][v_index].h_mid(), v_mid = gNodes[h_index][v_index].v_mid();
gNodes[h_index][v_index].sum_phones += add;
Update(left_child, down_child, left, MIN(right, h_mid), bottom, MIN(top, v_mid), add);
Update(left_child, up_child, left, MIN(right, h_mid), MAX(v_mid + 1, bottom), top, add);
Update(right_child, down_child, MAX(left, h_mid + 1), right, bottom, MIN(top, v_mid), add);
Update(right_child, down_child, MAX(left, h_mid + 1), right, MAX(v_mid + 1, bottom), top, add);
} int Query(int h_index, int v_index, short left, short right, short bottom, short top){
if (left == right || top == bottom){ //arrive to the point
return gNodes[h_index][v_index].sum_phones;
}
if (left > gNodes[h_index][v_index].right || right < gNodes[h_index][v_index].left
|| top < gNodes[h_index][v_index].bottom || bottom > gNodes[h_index][v_index].top){
return 0;
}
if (left > right || bottom > top){
return 0;
}
int left_child = 2 * h_index + 1, right_child = 2 * h_index + 2;
int up_child = 2 * v_index + 1, down_child = 2 * v_index + 2;
short h_mid = gNodes[h_index][v_index].h_mid(), v_mid = gNodes[h_index][v_index].v_mid();
int result = 0;
result += Query(left_child, down_child, left, MIN(right, h_mid), bottom, MIN(top, v_mid));
result += Query(left_child, up_child, left, MIN(right, h_mid), MAX(v_mid + 1, bottom), top);
result += Query(right_child, down_child, MAX(left, h_mid + 1), right, bottom, MIN(top, v_mid));
result += Query(right_child, down_child, MAX(left, h_mid + 1), right, MAX(v_mid + 1, bottom), top);
return result;
} int main(){
int ins;
int S, X, Y, A, L, B, R, T;
scanf("%d %d", &ins, &S);
BuildTree(0, 0, 0, S - 1, 0, S - 1);
while (scanf("%d", &ins)){
if (ins == 3){
break;
}
if (ins == 1){
scanf("%d %d %d", &X, &Y, &A);
Update(0, 0, X, X, Y, Y, A);
}
else if (ins == 2){
scanf("%d %d %d %d", &L, &B, &R, &T);
int result = Query(0, 0, L, R, B, T);
printf("%d\n", result);
}
}
return 0;
}
poj_1190 树状数组的更多相关文章
- BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]
1103: [POI2007]大都市meg Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2221 Solved: 1179[Submit][Sta ...
- bzoj1878--离线+树状数组
这题在线做很麻烦,所以我们选择离线. 首先预处理出数组next[i]表示i这个位置的颜色下一次出现的位置. 然后对与每种颜色第一次出现的位置x,将a[x]++. 将每个询问按左端点排序,再从左往右扫, ...
- codeforces 597C C. Subsequences(dp+树状数组)
题目链接: C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input standar ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
- BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]
3529: [Sdoi2014]数表 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1399 Solved: 694[Submit][Status] ...
- BZOJ 3289: Mato的文件管理[莫队算法 树状数组]
3289: Mato的文件管理 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 2399 Solved: 988[Submit][Status][Di ...
- 【Codeforces163E】e-Government AC自动机fail树 + DFS序 + 树状数组
E. e-Government time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...
- 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序
3881: [Coci2015]Divljak Time Limit: 20 Sec Memory Limit: 768 MBSubmit: 508 Solved: 158[Submit][Sta ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
随机推荐
- 【C#】遍历List列表的同时,移除访问到的元素
需求:遍历List列表,当访问的元素符合某一条件时,将该元素移除出列表. 注意点:使用foreach循环遍历无法做到边读边修改,所以要使用for循环. 例子: // 倒序遍历. for (int i ...
- C语言 · 报时助手
基础练习 报时助手 时间限制:1.0s 内存限制:512.0MB 锦囊1 判断,字符串输出. 锦囊2 按要求输出,判断特殊情况. 问题描述 给定当前的时间,请用英文的读法 ...
- 无法识别的属性 configProtectionProvider的解决方案
用RsaProtectedConfigurationProvider加密数据库连接字符串时,只要App.config有任何改动,都会提示无法识别的属性 configProtectionProvider ...
- java多线程有几种实现方法?线程之间如何同步
java中多线程的实现方法有两种:1.直接继承thread类:2.实现runnable接口: 同步的实现方法有五种:1.同步方法:2.同步代码块:3.使用特殊域变量(volatile)实现线程同步:4 ...
- Axel 快速下载
Axel 是一个轻量级下载程序,它和其他加速器一样,对同一个文件建立多个连接,每个连接下载单独的文件片段以更快地完成下载. Axel 支持 HTTP.HTTPS.FTP 和 FTPS 协议.它也可以使 ...
- vlan pvid vid access口 trunk口
VLAN技术浅谈 http://www.h3c.com.cn/MiniSite/H3care_Club/Data_Center/Net_Reptile/The_One/Home/Catalog/ ...
- java笔记知识点总结
1.switch case default 语句 : switch case 语句是一个条件选择语句,找到相同的case值做为入口,执行后面的程序:若所有的case都不满足,则找default入口:若 ...
- Graying the black box: Understanding DQNs
Zahavy, Tom, Nir Ben-Zrihem, and Shie Mannor. "Graying the black box: Understanding DQNs." ...
- C++异常抛出与捕获及处理
一.异常 迄今为止,我们处理程序中的错误一般都是用if语句测试某个表达式,然后处理错误的特定义代码. C++异常机制使用了三个新的关键字 (SEH(结构化异常处理)) try ──标识可能出现 ...
- maven 打包可执行jar的两种方法
1.修改pom.xml增加如下内容 <build> <pluginManagement> <plugins> <plugin> <groupId& ...