Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows. The area is divided into squares. The squares form an S * S matrix with the rows and columns numbered from 0 to S-1. Each square contains a base station. The number of active mobile phones inside a square can change because a phone is moved from a square to another or a phone is switched on or off. At times, each base station reports the change in the number of active phones to the main base station along with the row and the column of the matrix.

Write a program, which receives these reports and answers queries about the current total number of active mobile phones in any rectangle-shaped area.

Input

The input is read from standard input as integers and the answers to the queries are written to standard output as integers. The input is encoded as follows. Each input comes on a separate line, and consists of one instruction integer and a number of parameter integers according to the following table. 

The values will always be in range, so there is no need to check them. In particular, if A is negative, it can be assumed that it will not reduce the square value below zero. The indexing starts at 0, e.g. for a table of size 4 * 4, we have 0 <= X <= 3 and 0 <= Y <= 3.

Table size: 1 * 1 <= S * S <= 1024 * 1024 
Cell value V at any time: 0 <= V <= 32767 
Update amount: -32768 <= A <= 32767 
No of instructions in input: 3 <= U <= 60002 
Maximum number of phones in the whole table: M= 2^30 

Output

Your program should not answer anything to lines with an instruction other than 2. If the instruction is 2, then your program is expected to answer the query by writing the answer as a single line containing a single integer to standard output.

Sample Input

0 4
1 1 2 3
2 0 0 2 2
1 1 1 2
1 1 2 -1
2 1 1 2 3
3

Sample Output

3
4

题目:二维平面上单点加值操作,矩形区间求和操作。

  • 显然这个数据可以用二维树状数组秒

//poj1195树状数组
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=;
int sum[maxn][maxn],N;
int lowbit(int x) { return x&(-x); }
void add(int x,int y,int val)
{
for(int i=x;i<=N;i+=lowbit(i))
for(int j=y;j<=N;j+=lowbit(j))
sum[i][j]+=val;
}
int query(int x,int y)
{
int res=;
for(int i=x;i;i-=lowbit(i))
for(int j=y;j;j-=lowbit(j))
res+=sum[i][j];
return res;
}
int main()
{
int opt,a,b,x,y,val;
while(~scanf("%d",&opt)){
scanf("%d",&N);
memset(sum,,sizeof(sum));
while(scanf("%d",&opt)){
if(opt==) break;
if(opt==){
scanf("%d%d%d",&x,&y,&val);
add(x+,y+,val);
}
else{
scanf("%d%d%d%d",&x,&y,&a,&b);
printf("%d\n",query(a+,b+)+query(x,y)-query(a+,y)-query(x,b+));
}
}
} return ;
}
  • 但如果操作不变,二维平面变大,空间不够时,cdq分治就来了。

首先看下面之前,先回顾一下上面的题,二维树状树组可以做,复杂度为(nlg2n),只是空间变大后不行。此题引用cdq分治是为了降二维树状数组为一维。(避免读者误以为cdq分治优化的是复杂度,其实复杂度没有降低。)

nmphy自诉:
1,为了描述,这里假设分治[l,r]部分时,处理[l,mid]的增加对[mid+1,r]的影响叫做“合并”过程。
2,以下的l,mid,r均是指第几个操作,即按时间排序后是第几个操作,而不是x坐标或者y坐标,不要搞混淆。
我们假设有q个操作(即按时间排序),现在在解决[l,r]这几个操作。
可以肯定:当前合并过程中[mid+,r]的增加的值全部来自于[l,mid]。
为什么呢?l之前增加的值对[mid+1,r]的影响呢呢?[mid+,R]内部操作增加的值对内部后面的影响呢?
仔细一看,l之前增加的值在更大的分治里面(即[l,r]属于[L,R],假设[L,R]=[L,mid]+[l,r],那么l之前的[L,mid]部分就在这里合并处理);
而[mid+,r]增加的值在更新的分治里(即[mid+,(mid++r)/],[(mid++r)/+,r])。
从而保证了前面的增加对后面的询问都被考虑到。
但是[l,mid]对[mid+,r]处理时,增加值使用了一次;合并后[l,r]对[r+,r]处理时,显然[l,mid]的增加值又使用了一次。
所以在处理完内部后,还得减去增加值

上面有点乱的话自己来问我,我觉得理解上面这段话还是很重要的!

所谓cdq分治,就是分治所有操作,计算[l,mid]中的修改对[mid+,r]中的询问的影响。
无法理解的同学可以借助归并排序的思想思考。
抄袭别人讲以上的话吧
、T(n)=2T(n/)+O(kn)的解是T(n)=O(kn log n)
、T(n)=2T(n/)+O(kn log n)的解是T(n)=O(kn log^ n)
、T(n)=2T(n/)+O(k)的解是T(n)=O(kn)

所以cdq分治的复杂度也可以简单的算出来了。
cdq能处理的题目必须满足:、允许离线 、前面的修改对后面的影响很容易算出来 比如说这一题
在[l,mid]部分的修改按x排序从小到大加进一个树状数组里,不断更新对[mid+,r]的影响。
复杂度就是第二种计算方式,可就是O(q log^ w)

因为我们从下向上扫描,所以不需要记录y轴方向的树状数组,只需要跟新x方向即可。

CDQ分治中,首先按x来排序,对t这个维度进行分治。
那么t<=mid的更新操作都能影响到t'>=mid+1的查询结果。
所以在CDQ(l,r)中,按照x从小到大扫一遍所有操作,遇到更新操作就在树状数组上插入y值(y值离散过),
遇到查询操作就给该操作的结果加上树状数组上查询到的sum(,y)的值。
接下来用类似归并排序的方法,把t<=mid的操作都放到数组左半部分,t>=mid+1的操作都放到右半部分
这么做之后两半部分的y依然是有序的,就可以递归处理两半部分之间的更新操作对查询操作产生的影响了。
你瞅啥?
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lowbit(x) ((x)&(-(x)))
const int Maxn=;
int x1[Maxn],x2[Maxn],y1[Maxn],y2[Maxn],tr[Maxn];
int a[Maxn],b[Maxn],c[Maxn],opt[Maxn],ans[Maxn];
int n,m,s,w,i;
struct arr{
int x,l,r,k,c;
bool operator <(const arr &a) const { return x<a.x; }
}qk[Maxn];
struct ad{
int x,y,w;
bool operator <(const ad &a) const { return x<a.x; }
}g[Maxn];
int query(int x){
int ret=;
for (int i=x;i>;i-=lowbit(i)) ret+=tr[i];
return ret;
}
void add(int x,int s){
for(int i=x;i<=m;i+=lowbit(i)) tr[i]+=s;
}
void combine(int l,int r)
{
int mid=(l+r)>>,t=,tt=,i,j;
for(i=mid+;i<=r;i++)
if(opt[i]==){
qk[++t]=(arr){x1[i]-, y1[i], y2[i], i, };
qk[++t]=(arr){x2[i], y1[i], y2[i], i, };
}
sort(qk+,qk+t+); //按x排序
for(i=l;i<=mid;i++)
if(opt[i]==) g[++tt]=(ad){x1[i],y1[i],x2[i]};
sort(g+,g+tt+);
for(i=,j=;i<=tt;i++){
while(j<=t&&qk[j].x<g[i].x){
if (qk[j].c==) ans[qk[j].k]-=query(qk[j].r)-query(qk[j].l-);
else ans[qk[j].k]+=query(qk[j].r)-query(qk[j].l-);
j++;
} add(g[i].y,g[i].w);
}
while(j<=t){
if(qk[j].c==) ans[qk[j].k]-=query(qk[j].r)-query(qk[j].l-);
else ans[qk[j].k]+=query(qk[j].r)-query(qk[j].l-);
j++;
}
for(i=;i<=tt;i++) add(g[i].y,-g[i].w);//减去增加值
}
void cdq(int l,int r){
if(l==r) return;
int mid=(l+r)>>;
cdq(l,mid);
combine(l,r); //前+前半截对后半截的影响+后
cdq(mid+,r);
}
int main(){
scanf("%d%d",&s,&w); n=; //s是初始值,此题为0
while (true){
scanf("%d",&opt[n]);
if(opt[n]==||opt[n]==) break;
if(opt[n]==){
scanf("%d%d%d",&x1[n],&y1[n],&x2[n]);
c[++m]=y1[n];
}else
if(opt[n]==){
scanf("%d%d%d%d",&x1[n],&y1[n],&x2[n],&y2[n]);
ans[n]+=s*(x2[n]-x1[n]+)*(y2[n]-y1[n]+);
c[++m]=y1[n]; c[++m]=y2[n]; //c是复制y坐标来离散
} n++;
}
sort(c+,c+m+); //按y排序
m=unique(c+,c+m+)-(c+); //离散
for(i=;i<n;i++){
y1[i]=lower_bound(c+,c+m+,y1[i])-c;
if(opt[i]==) y2[i]=lower_bound(c+,c+m+,y2[i])-c;
} cdq(,--n);
for(i=;i<=n;i++) if(opt[i]==) printf("%d\n",ans[i]);
return ;
}

园丁的烦恼 SHOI2007 BZOJ 1935

  【模板】树状数组 1 luogu P3374

  Mokia BZOJ 1176

  陌上花开 BZOJ 3262

  简单题BZOJ 2683

  动态逆序对 CQOI2011 BZOJ 3295

POJ1195Mobile phones (从二维树状数组到cdq分治)的更多相关文章

  1. 【 HDU - 4456 】Crowd (二维树状数组、cdq分治)

    BUPT2017 wintertraining(15) #5A HDU 4456 题意 给你一个n行n列的格子,一开始每个格子值都是0.有M个操作,p=1为第一种操作,给格子(x,y)增加z.p=2为 ...

  2. poj 1195:Mobile phones(二维树状数组,矩阵求和)

    Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 14489   Accepted: 6735 De ...

  3. (简单) POJ 1195 Mobile phones,二维树状数组。

    Description Suppose that the fourth generation mobile phone base stations in the Tampere area operat ...

  4. POJ 1195 Mobile phones (二维树状数组)

    Description Suppose that the fourth generation mobile phone base stations in the Tampere area operat ...

  5. POJ 1195 Mobile phones【二维树状数组】

    <题目链接> 题目大意: 一个由数字构成的大矩阵,开始是全0,能进行两种操作1) 对矩阵里的某个数加上一个整数(可正可负)2) 查询某个子矩阵里所有数字的和要求对每次查询,输出结果 解题分 ...

  6. POJ-2155:Matrix(二维树状数祖)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 31892   Accepted: 11594 Descript ...

  7. POJ_1195 Mobile phones 【二维树状数组】

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u013912596/article/details/33802561 题目链接:id=1195&qu ...

  8. POJ 1195 Mobile phones(二维树状数组)

                                                                  Mobile phones Time Limit: 5000MS   Mem ...

  9. POJ 1195 Mobile phones (二维树状数组或线段树)

    偶然发现这题还没A掉............速速解决了............. 树状数组和线段树比较下,线段树是在是太冗余了,以后能用树状数组还是尽量用......... #include < ...

随机推荐

  1. 集团管控的历史读本——Leo鉴书76

    当下中国管理咨询界比較火的课题之中的一个就是"集团管控".公司大了之后怎样正好的用人.怎样对下属分公司不失控制.怎样在二代接手之后系统仍然稳固.种种问题都在困扰着企业们.假设我们把 ...

  2. D类功放基础简介

    DAC和D类PA的开关时序是先开dac再开D类pa,先关D类pa再关dac

  3. 最短路 uva12661 Funny Car Racing

    传送门:点击打开链接 题意:给你有向图,每条边呈周期性开放,即开放a时间,再关闭b时间.再开放a时间以此类推 假设时间不足以穿过这条路则不能走.你能够在节点等待时间,问从s走到t所须要的最小时间 细致 ...

  4. iOS程序自动检测更新的实现

      本文转载至 http://blog.csdn.net/davidsph/article/details/8931718 App Store自动更新itunes     之前项目需要用到app自动更 ...

  5. 前后端分离之fiddler前端开发代理 autoresponder 正则表达式 regex:(?insx) 修正符详解

    regex:(?isx)^http://127.0.0.1:3000(/dlscene)?/order/(\w*) http://127.0.0.1:8080/dlscene/order/$2 上面这 ...

  6. sql中decode()重要函数使用

    decode()函数简介: 主要作用:将查询结果翻译成其他值(即以其他形式表现出来,以下举例说明): 使用方法: Select decode(columnname,值1,翻译值1,值2,翻译值2,.. ...

  7. 一些重要的地址:md5在线解密破解

    md5在线解密破解:https://www.cmd5.com/

  8. Makefile注意点总结

    1 "="和":=" "="号赋值时,如果右边的值里面有未展开的变量,要等到整个Makefile的变量处理完之后,再展开,也就是说,如果该未 ...

  9. CrystalReport runtime的下载地址

    SAP网站的东西实在太多了,找个CrytalReport都费劲.13.*版的可以通过下面的地址下载: SAP Crystal Reports, developer version for Micros ...

  10. Mac环境,React native错误解决方案

    运行react-native run-android,报错如下图:     运行react-native run-ios正常,但 react-native run-android时,提示错误: 在网上 ...