题面

Time Limit: 50 Sec  Memory Limit: 128 MB

Description

你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作:

命令

参数限制

内容

1 x y A

1<=x,y<=N,A是正整数

将格子x,y里的数字加上A

2 x1 y1 x2 y2

1<=x1<= x2<=N

1<=y1<= y2<=N

输出x1 y1 x2 y2这个矩形内的数字和

3

终止程序

Input

输入文件第一行一个正整数N。
接下来每行一个操作。
 

Output

对于每个2操作,输出一个对应的答案。
 

Sample Input

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

1<=N<=500000,操作数不超过200000个,内存限制20M。
对于100%的数据,操作1中的A不超过2000。
 
解题思路
 
cdq分治,原问题分为三维:时间,横坐标,纵坐标,之后cdq分治解决时间, 排序解决横坐标,树状数组解决纵坐标,时间复杂度O(nlog^2n)
 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib> using namespace std;
const int MAXN = ;
typedef long long LL; inline int rd(){
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {f=ch=='-'?:;ch=getchar();}
while(isdigit(ch)) {x=(x<<)+(x<<)+ch-'';ch=getchar();}
return f?x:-x;
} int n,cnt,Num;
LL f[MAXN],ans[MAXN]; struct Query{
int x,y,type;
int val,id,num;
friend bool operator<(const Query A,const Query B){
if(A.x!=B.x) return A.x<B.x;
if(A.y!=B.y) return A.y<B.y;
return A.type<B.type;
}
}q[MAXN<<],tmp[MAXN<<]; void add(int x,int y){
for(;x<=n;x+=x&-x) f[x]+=y;
} LL sum(int x){
LL ret=;
for(;x;x-=x&-x) ret+=f[x];
return ret;
} void Clear(int x){
for(;x<=n;x+=x&-x) f[x]=;
} void cdq(int l,int r){
if(l==r) return;
int mid=l+r>>;cdq(l,mid);cdq(mid+,r);
int L=l,R=mid+,o=;
while(L<=mid && R<=r) {
if(q[L]<q[R]) {
if(q[L].type==) add(q[L].y,q[L].val);
tmp[++o]=q[L++];
}
else{
if(q[R].type==) ans[q[R].num]+=q[R].val*sum(q[R].y);
tmp[++o]=q[R++];
}
}
while(L<=mid) tmp[++o]=q[L++];
while(R<=r) {
if(q[R].type==) ans[q[R].num]+=q[R].val*sum(q[R].y);
tmp[++o]=q[R++];
}
for(register int i=l;i<=mid;i++) if(q[i].type==) Clear(q[i].y);
for(register int i=;i<=o;i++) q[i+l-]=tmp[i];
} int main(){
n=rd();
int op,x1,x2,y1,y2;
while(){
op=rd();if(op==) break;
if(op==) {
q[++cnt].type=op;q[cnt].x=rd();q[cnt].y=rd();
q[cnt].val=rd();q[cnt].id=cnt;
}
else{
x1=rd(),y1=rd(),x2=rd(),y2=rd();
q[++cnt].type=op;q[cnt].x=x1-;q[cnt].y=y1-;
q[cnt].val=;q[cnt].id=cnt;q[cnt].num=++Num;
q[++cnt].type=op;q[cnt].x=x1-;q[cnt].y=y2;
q[cnt].val=-;q[cnt].id=cnt;q[cnt].num=Num;
q[++cnt].type=op;q[cnt].x=x2;q[cnt].y=y1-;
q[cnt].val=-;q[cnt].id=cnt;q[cnt].num=Num;
q[++cnt].type=op;q[cnt].x=x2;q[cnt].y=y2;
q[cnt].val=;q[cnt].id=cnt;q[cnt].num=Num;
}
}
// cout<<cnt<<endl;
// for(int i=1;i<=cnt;i++)
// cout<<q[i].type<<" "<<q[i].x<<" "<<q[i].y<<" "<<q[i].val<<" "<<q[i].id<<" "<<q[i].num<<endl;
cdq(,cnt);
for(int i=;i<=Num;i++) printf("%lld\n",ans[i]);
return ;
}

BZOJ 2683: 简单题(CDQ 分治)的更多相关文章

  1. BZOJ 2683: 简单题 [CDQ分治]

    同上题 那你为什么又发一个? 因为我用另一种写法又写了一遍... 不用排序,$CDQ$分治的时候归并排序 快了1000ms... #include <iostream> #include ...

  2. BZOJ 2683 简单题 cdq分治+树状数组

    题意:链接 **方法:**cdq分治+树状数组 解析: 首先对于这道题,看了范围之后.二维的数据结构是显然不能过的.于是我们可能会考虑把一维排序之后还有一位上数据结构什么的,然而cdq分治却可以非常好 ...

  3. BZOJ 2683 简单题 ——CDQ分治

    [题目分析] 感觉CDQ分治和整体二分有着很本质的区别. 为什么还有许多人把他们放在一起,也许是因为代码很像吧. CDQ分治最重要的是加入了时间对答案的影响,x,y,t三个条件. 排序解决了x ,分治 ...

  4. bzoj 1176: [Balkan2007]Mokia&&2683: 简单题 -- cdq分治

    2683: 简单题 Time Limit: 50 Sec  Memory Limit: 128 MB Description 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要 ...

  5. 【BZOJ-1176&2683】Mokia&简单题 CDQ分治

    1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1854  Solved: 821[Submit][St ...

  6. BZOJ 2683: 简单题

    2683: 简单题 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 913  Solved: 379[Submit][Status][Discuss] ...

  7. bzoj2683简单题 cdq分治

    2683: 简单题 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 1803  Solved: 731[Submit][Status][Discuss] ...

  8. BZOJ 2683: 简单题(CDQ分治 + 树状数组)

    BZOJ2683: 简单题(CDQ分治 + 树状数组) 题意: 你有一个\(N*N\)的棋盘,每个格子内有一个整数,初始时的时候全部为\(0\),现在需要维护两种操作: 命令 参数限制 内容 \(1\ ...

  9. 【BZOJ1176】[Balkan2007]Mokia/【BZOJ2683】简单题 cdq分治

    [BZOJ1176][Balkan2007]Mokia Description 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=1600 ...

随机推荐

  1. Android Scroller简单用法 --View滚动

    转:http://ipjmc.iteye.com/blog/1615828 Android里Scroller类是为了实现View平滑滚动的一个Helper类.通常在自定义的View时使用,在View中 ...

  2. ims注册与注销

    ims注册流程: 步骤1:当IMS和SIM访问已经就绪时,IMC将在满足条件后触发IMS注册到IMCB.步骤2.3:IMCB请求IMSA/IMSM获取IMS PDN和P-CSCF,然后触发VoLTE ...

  3. JavaScript实现几种常见的图形

    一.四种常见的三角形 第一种三角形: for(var i=1;i<=5;i++){        for( var j=i;j<=5;j++){                 docum ...

  4. 8.关于ActiveMQ、RocketMQ、RabbitMQ、Kafka一些总结和区别

    这是一篇分享文 转自:http://www.cnblogs.com/williamjie/p/9481780.html  尊重原作,谢谢 消息队列 为什么写这篇文章? 博主有两位朋友分别是小A和小B: ...

  5. Python调用DLL动态链接库——ctypes使用

    最近要使用python调用C++编译生成的DLL动态链接库,因此学习了一下ctypes库的基本使用. ctypes是一个用于Python的外部函数库,它提供C兼容的数据类型,并允许在DLL或共享库中调 ...

  6. matlab-使用技巧

    sel(1:100); 1 2 3 4 5 ...100 X(sel, :); 1.......2.......3.......4.......5..........100...... nn_para ...

  7. 【学术篇】洛谷1550——打井Watering Hole

    题目の传送门:https://www.luogu.org/problem/show?pid=1550 精简版题意(本来就精简了不是么):n个点,每个点可以选择打井或从别的有水的点引水,求所有点都有水用 ...

  8. CodeForces - 27E

    https://vjudge.net/problem/CodeForces-27E 求因子个数为n的最小的数dfs枚举质因子的幂 #include <iostream> #include ...

  9. DRF初识

    目录 Web API接口 什么是Web API接口 接口四大特征 接口文档的编写测试 restful接口规范 url链接设计 五大请求方式 响应结果 DRF框架安装 基于原生Django实现十大接口 ...

  10. 前缀后缀——cf1167E

    想了很久没弄明白,对于边界的情况还是有问题 等题解出了再看看 然后枚举每个后缀r,找到比它小,并且在其左边的前缀l,那么删<=l,r-1的都可以 最后的二分很迷:要多考虑特殊情况:前缀跑到后缀后 ...