CDQ求子矩阵的和
Description
维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000.
Input
第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小
接下来每行为一下三种输入之一(不包含引号):
"1 x y a"
"2 x1 y1 x2 y2"
"3"
输入1:你需要把(x,y)(第x行第y列)的格子权值增加a
输入2:你需要求出以左下角为(x1,y1),右上角为(x2,y2)的矩阵内所有格子的权值和,并输出
输入3:表示输入结束
Output
对于每个输入2,输出一行,即输入2的答案
Sample Input
0 4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
Sample Output
3
5
HINT
保证答案不会超过int范围
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<map> using namespace std; #define FOU(i,x,y) for(int i=x;i<=y;i++)
#define FOD(i,x,y) for(int i=x;i>=y;i--)
#define MEM(a,val) memset(a,val,sizeof(a))
#define PI acos(-1.0) const double EXP = 1e-;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const ll MINF = 0x3f3f3f3f3f3f3f3f;
const double DINF = 0xffffffffffff;
const int mod = 1e9+;
const int N = 2e6+; struct node{
int typ; //类型
int x,y;
int id; //记录输入相对位置
int val;
int pos; //输出答案用
}a[N],tmp[N]; int n,w,tot;
int ans[]; //答案数组 bool cmp(node a,node b){
if(a.x==b.x&&a.y==b.y)
return a.id<b.id;
if(a.x==b.x)
return a.y<b.y;
return a.x<b.x;
} int tree[N]; //tree数组按二进制存,根据n的末尾0的个数存取,树状数组 int lowbit(int x)
{
return x&(-x);
} int Query(int x) //返回1到x的前缀和
{
int res=;
while(x)
{
res+=tree[x];
x-=lowbit(x);
}
return res;
} void Add(int x,int v) //实现a[x]+v;
{
while(x<=n) //注意这里是小于等于k,还是n,k是数据范围
{
tree[x]+=v;
x+=lowbit(x);
}
} void clearr(int x){
while(x<=n){
if(tree[x]==)
break;
tree[x]=;
x+=lowbit(x);
}
} void cdq(int l,int r){
if(l>=r)
return ;
int mid=l+r>>;
cdq(l,mid);
cdq(mid+,r);
int p=l,q=mid+,k=l;
while(p<=mid&&q<=r){
if(a[p].id<=a[q].id){
if(a[p].typ==)
Add(a[p].y,a[p].val);
tmp[k++] = a[p++];
}
else{
if(a[q].typ==)
ans[a[q].pos]+=Query(a[q].y)*a[q].val;
tmp[k++] = a[q++];
}
}
while(p<=mid){
if(a[p].typ==)
Add(a[p].y,a[p].val);
tmp[k++]=a[p++];
}
while(q<=r){
if(a[q].typ==)
ans[a[q].pos]+=Query(a[q].y)*a[q].val;
tmp[k++]=a[q++];
}
for(int i=l;i<=r;i++){
clearr(a[i].y);
a[i]=tmp[i];
}
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
std::ios::sync_with_stdio(false);
int s;
scanf("%d%d",&s,&n);
int opt,x,y,val,x1,x2,y1,y2;
tot=;
int m=;
while(~scanf("%d",&opt)){
if(opt==)
break;
if(opt==){
scanf("%d%d%d",&x,&y,&val);
a[++m]=node{,x,y,m,val,};
}
else{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
++tot;
//比x2,y2小的都加上,val赋值1
a[++m]=node{,x2,y2,m,,tot};
//因为他是中间矩阵,而我们加是1~x,1~y的加,所以多出来的要赋值成-1,来减掉,val赋值-1
a[++m]=node{,x2,y1-,m,-,tot};
a[++m]=node{,x1-,y2,m,-,tot};
//这里多减了一次,要加回来,val赋值1
a[++m]=node{,x1-,y1-,m,,tot}; ans[tot]+=(x2-x1+)*(y2-y1+)*s; //答案赋初值
}
}
sort(a+,a++m,cmp);
cdq(,m);
for(int i=;i<=tot;i++)
printf("%d\n",ans[i]);
return ;
}
CDQ求子矩阵的和的更多相关文章
- ACM 中 矩阵数据的预处理 && 求子矩阵元素和问题
我们考虑一个$N\times M$的矩阵数据,若要对矩阵中的部分数据进行读取,比如求某个$a\times b$的子矩阵的元素和,通常我们可以想到$O(ab)$的遍历那个子矩阵,对它的各 ...
- bzoj 3295 CDQ求动态逆序对
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk mak ...
- [ZJOI2007]棋盘制作 悬线法dp 求限制下的最大子矩阵
https://www.luogu.org/problemnew/show/P1169 第一次听说到这种dp的名称叫做悬线法,听起来好厉害 题意是求一个矩阵内的最大01交错子矩阵,开始想的是dp[20 ...
- P2258子矩阵
传送 一道看起来就很暴力的题. 这道题不仅暴力,还要用正确的姿势打开暴力. 因为子矩阵的参数有两个,一个行一个列(废话) 我们一次枚举两个参数很容易乱对不对?所以我们先枚举行,再枚举列 枚举完行,列, ...
- dp例题03. 最大子矩阵和
题目Description: 给出一个矩阵, 求子矩阵(可以是其本身)数之和的最大值 Input: 第一行 为行数n和列数m (n≤500, m≤500) 接下来为一个n行m列的矩阵 (每 ...
- bzoj1176 2683
我的第一道cdq分治题清明做了一下cdq分治的几道题,感觉这个东西实在是太厉害了离线大法好!关于几个经典的非数据结构做法具体可以看xhr神犇2013年的论文应用cdq分治的前提条件是不强制在线,修改操 ...
- hdu2888 二维RMQ
Check Corners Time Limit: 2000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- Java知识点总结(不定时更新)
1.基于分代的垃圾收集算法 设计思路:把对象按照寿命长短来分组,分为年轻代和年老代,新创建的对象被分在年轻代,如果对象经过几次回收后仍然存活,那么再把这个对象划分到年老代.年老代的收集频率不像年轻代那 ...
- FZU 1018 枚举dp
题意 给出一个数字组成的立方体 在其中选取一个体 使这个体中的数字之和最小 不可以不选 fzu的题目分类动态规划里面不是按难度排得 是按照题号..记得以前做题碰到过算 矩阵里面求子矩阵的最大和的 不会 ...
随机推荐
- so easy(并查集+unordered_map)
There are nn points in an array with index from 11 to nn, and there are two operations to those poin ...
- mac键盘在ubuntu下开启fn功能按键
转载:http://wiki.ubuntu.org.cn/UbuntuHelp:AppleKeyboard Change Function Key behavior This section of t ...
- RabbitMq学习3-工作队列(Work queues)
工作队列(又称:任务队列——Task Queues)是为了避免等待一些占用大量资源.时间的操作.当我们把任务(Task)当作消息发送到队列中,一个运行在后台的工作者(worker)进程就会取出任务然后 ...
- TApplication,TForm,TControl,TComponent,TWinControl研究(博客索引)good
TApplication,TForm,TControl,TComponent,TWinControl研究 http://blog.csdn.net/suiyunonghen/article/detai ...
- 理解PHP面向对象三大特性
一.封装性 目的:保护类里面的数据,让类更安全, protected和private只能在类中或子类访问,通过public提供有限的接口供外部访问,封装是控制访问,而不是拒绝访问 封装关键字:publ ...
- Vue之路由跳转 传参 aixos 和cookie
一.路由跳转 1.1 项目的初始化 vue create m-proj >>>创建vue项目 精简vue项目的 views 视图 About(基本是删除的) Home.(可以 ...
- 05java基础
1.BigInteger和BigDecimal类 package cn.jxufe.java.chapter5.demo01; import java.math.BigInteger; public ...
- jenkins插件send files or execute commands over ssh插件parameterized publishing选项使用
1.设置一个参数 2.设置label 3.勾选parameterized publishing
- spring jpa 带参数分页查询(一)
1.写个接口继承JpaRepository @NoRepositoryBean public interface BaseRepository<T,PK extends Serializable ...
- overflow:hidden失效问题
2018-08-03 Questions about work 这几天开发的时候遇到了个问题,如图1. 写了个demo demo 地址 由于页面并没有进行整体缩放,导致在小屏幕手机上显示会有异常.PM ...