hdu4456 Crowd(二维树状数组)
题意:给出一个n*n的矩阵,然后m个operation,1表示坐标(x,y)的值加z,2表示与坐标(x,y)的曼哈顿距离不超过z的点的权值和。
解题思路:将矩阵側过来45度。发现询问的时候,有效的点构成的事实上是一个矩阵。
然后就变成了单点改动。求矩阵和的问题。
我们考虑裸二维树状数组的做法。会发现矩阵太大,可是注意到,初始的时候,矩阵里面全部的值都为0,那么这个二维树状数组中。有效的点就是改动的那些点,以及掌控这些点的区间。这里总的状态数仅仅有m*logn*logn。所以我们把operation都拿出来,然后将有改动的状态映射到序列中就可以。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#define lowbit(x) (x&(-x))
using namespace std ;
struct Operation {
int op , x , y , z ;
} p[88888] ;
int base = 100000 ;
const int N = 2222222 ;
vector<int> mp ;
int val[N] , tot , n , m ;
const int maxn = 22222 ; inline int get ( int x , int y ) {
x = x * base + y ;
y = lower_bound(mp.begin(),mp.end(),x) - mp.begin() ;
if ( y == tot || mp[y] != x ) return -1 ;
return y ;
} void update ( int x , int y , int z ) {
while ( x < n*2+100 ) {
int pos = y ;
while ( pos < n*2+100 ) {
int now = get (x,pos) ;
val[now] += z ;
pos += lowbit ( pos ) ;
}
x += lowbit ( x ) ;
}
} int sum ( int x , int y ) {
int ret = 0 ;
while ( x ) {
int pos = y ;
while ( pos ) {
int now = get ( x , pos ) ;
if (now != -1) ret += val[now] ;
pos -= lowbit ( pos ) ;
}
x -= lowbit ( x ) ;
}
return ret ;
} int query ( int x1 , int y1 , int x2 , int y2 ) {
int ret1 = sum(x1-1,y1-1) , ret2 = sum(x2,y2) , ret3 = sum(x1-1,y2) , ret4 = sum(x2,y1-1) ;
// printf ( "ret2 = %d\n" , ret2 ) ;
return ret1+ret2-ret3-ret4 ;
} int get_num () {
int n = 0 , flag = 1 ;
char c ;
while ( (c = getchar ()) && c != '-' && (c<'0'||c>'9') ) ;
if ( c == '-' ) flag = -1 ;
else n = c - '0' ;
while ( (c = getchar ()) && c >= '0' && c <= '9' ) n = n * 10 + c - '0' ;
return n * flag ;
} void add ( int t , int x , int y ) {
while ( x < n*2+100 ) {
int pos = y ;
while ( pos < n*2+100 ) {
// if ( tot == N - 1 ) while (1) ;
mp.push_back ( x * base + pos ) ;
pos += lowbit ( pos ) ;
}
x += lowbit ( x ) ;
}
} void read ( int i ) {
p[i].op = get_num () ;
p[i].x = get_num () ;
p[i].y = get_num () ;
p[i].z = get_num () ;
int x = p[i].x + p[i].y - 1 , y = n - p[i].x + p[i].y ;
if ( p[i].op == 1 ) add ( 1 , x , y ) ;
} int main () {
while ( scanf ( "%d" , &n ) && n ) {
scanf ( "%d" , &m ) ;
mp.clear () ;
memset ( val , 0 , sizeof ( val ) ) ;
for ( int i = 1 ; i <= m ; i ++ )
read ( i ) ;
sort ( mp.begin() , mp.end() ) ;
vector<int>::iterator it = unique(mp.begin() , mp.end()) ;
mp.erase(it,mp.end()) ;
// tot = unique ( mp + 1 , mp + tot + 1 ) - mp - 1 ;
tot = mp.size () ;
for ( int i = 1 ; i <= m ; i ++ ) {
int op , x , y , z ;
op = p[i].op ;
x = p[i].x ;
y = p[i].y ;
z = p[i].z ;
// printf ( "op = %d , x = %d , y = %d , z = %d\n" , op , x , y , p[i].z ) ;
int xx = x + y - 1 , yy = n - x + y ;
if ( op == 1 ) {
update ( xx , yy , z ) ;
} else {
int x1 = std::max ( 1 , xx - z ) ;
int y1 = std::max ( 1 , yy - z ) ;
int x2 = std::min ( 2*n-1 , xx + z ) ;
int y2 = std::min ( 2*n-1 , yy + z ) ;
printf ( "%d\n" , query ( x1 , y1 , x2 , y2 ) ) ;
}
}
}
return 0 ;
}
hdu4456 Crowd(二维树状数组)的更多相关文章
- 【 HDU - 4456 】Crowd (二维树状数组、cdq分治)
BUPT2017 wintertraining(15) #5A HDU 4456 题意 给你一个n行n列的格子,一开始每个格子值都是0.有M个操作,p=1为第一种操作,给格子(x,y)增加z.p=2为 ...
- 二维树状数组 BZOJ 1452 [JSOI2009]Count
题目链接 裸二维树状数组 #include <bits/stdc++.h> const int N = 305; struct BIT_2D { int c[105][N][N], n, ...
- HDU1559 最大子矩阵 (二维树状数组)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1559 最大子矩阵 Time Limit: 30000/10000 MS (Java/Others) ...
- POJMatrix(二维树状数组)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 22058 Accepted: 8219 Descripti ...
- poj 1195:Mobile phones(二维树状数组,矩阵求和)
Mobile phones Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 14489 Accepted: 6735 De ...
- Codeforces Round #198 (Div. 1) D. Iahub and Xors 二维树状数组*
D. Iahub and Xors Iahub does not like background stories, so he'll tell you exactly what this prob ...
- POJ 2155 Matrix(二维树状数组+区间更新单点求和)
题意:给你一个n*n的全0矩阵,每次有两个操作: C x1 y1 x2 y2:将(x1,y1)到(x2,y2)的矩阵全部值求反 Q x y:求出(x,y)位置的值 树状数组标准是求单点更新区间求和,但 ...
- [poj2155]Matrix(二维树状数组)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 25004 Accepted: 9261 Descripti ...
- POJ 2155 Matrix (二维树状数组)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17224 Accepted: 6460 Descripti ...
随机推荐
- 【BIEE】MDS-01377:无法从使用 JNDI 名称 “jdbc/mds/owsm” 配置的数据源获取数据库连接
这是一次意外关机情况,BIEE环境是window server2008,但是一次意外情况,BIEE自动关机了,造成开启成功新启动BIEE产生如下错误: 错误产生后,倒腾了半天,并没发现什么问题,只是通 ...
- DEV 第三方控件报表分类汇总
最近这段时间难得空闲,于是打算做个报表功能,主要实现数据的分类汇总,以便不时之需.首先看看效果: 主要是根据工程类型这个字段进行分类,每个分类下对应的项目金额进行求和,当然,你也可以根据实际需求,进行 ...
- 使用vs远程调试iis站点
在vs安装目录下IDE文件夹下的Remote Debugger 复制到服务器运行 启动msvsmon.exe msvsmon.exe启动后设置远程连接不验证身份 vs中 调试→附加到进程 ip+端口访 ...
- 安卓端OCR文字识别之番外篇
拍照识别------OCR怎样在移动端大放异彩 大家好.我是文通晓伟.非常高兴能和大家共同探讨一下OCR识别技术在安卓端的应用. 首先坦白交代,我不是技术流,我是销售狗. 每天有打不完的电话和做不完的 ...
- How to fix Cannot change version of project facet Dynamic Web Module to 3.0 Error in Eclipse---转载
How to fix Cannot change version of project facet Dynamic Web Module to 3.0 Error in Eclipse 原文:http ...
- Linux 基础学习(第一节)
IP地址的配置 配置临时IP地址 ifconfig etho 192.168.0.91 255.255.255.0 图形化下面配置IP地址: 重启网卡服务: shell环境配置网卡信息 必备的参数 关 ...
- 百度语音识别demo:去掉离线识别功能
如果离线识别功能不是必须的,则为了减小包体积,可按下面方法将官方demo中的离线功能去掉: 1,删除loadOfflineEngine调用.2,删除data和license文件夹. 如此可使包体积减少 ...
- PHP写webservice服务端
1) WebService技术介绍 WebService是一种跨编程语言和跨操作系统平台的远程调用技术.仅仅有通过Web Service,client和server才可以自由的用HTTP进行通信.不论 ...
- 为什么 Objective-C 很难
转自:http://www.oschina.net/question/213217_41058 作为一个Objective-C的coder,我总能听到一部分人在这门语言上抱怨有很多问题.他们总在想快速 ...
- 2.Stacks(堆栈)
一.概述 C++ Stack(堆栈) 是一个容器类的改编,为程序员提供了堆栈的全部功能,也就是说实现了一个先进后出(FILO)的数据结构. 二.常用API empty() 堆栈为空则返回真 pop() ...