【BZOJ-1176&2683】Mokia&简单题 CDQ分治
1176: [Balkan2007]Mokia
Time Limit: 30 Sec Memory Limit: 162 MB
Submit: 1854 Solved: 821
[Submit][Status][Discuss]
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
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
Sample Output
5
HINT
保证答案不会超过int范围
Source
2683: 简单题
Time Limit: 50 Sec Memory Limit: 128 MB
Submit: 821 Solved: 339
[Submit][Status][Discuss]
Description
|
命令 |
参数限制 |
内容 |
|
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
Output
Sample Input
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
Sample Output
5
HINT
Source
Solution
不能直接硬做,所以利用CDQ分治,大致的过程是:
首先把一个询问操作,拆成4个..++--;
然后我们所有操作进行排序,按x维排序;
然后对y维建立树状数组,这里我们可以发现,如果按x从小到大的处理的话,一次询问,相当于是对y维取前缀和;
然后CDQ(l,r),枚举这些操作,如果修改操作序号<=mid,那么就修改;如果查询操作序号>mid那么就计算答案。这样按x进行的排序和输入顺序就不矛盾了,可以得到正确答案
然后还要还原,然后递归分治即可
Code
BZOJ2683:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
inline int read()
{
int x=; char ch=getchar();
while (ch<'' || ch>'') {ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x;
}
#define MAXQ 200010
#define MAXN 500010
int S,W,ans[MAXQ];
namespace BIT
{
int tree[MAXN];
inline int lowbit(int x) {return x&-x;}
inline void Change(int pos,int D) {for (int i=pos; i<=W; i+=lowbit(i)) tree[i]+=D;}
inline int Query(int pos) {int re=; for (int i=pos; i; i-=lowbit(i)) re+=tree[i]; return re;}
}
using namespace BIT;
struct AskNode
{
int id,x,y,opt,del,ID;
bool operator < (const AskNode & A) const
{
return (x==A.x && y==A.y)? opt<A.opt: ((x==A.x)? y<A.y:x<A.x);
}
}q[MAXQ<<],tmp[MAXQ<<];
void CDQ(int l,int r)
{
if (l==r) return;
int mid=(l+r)>>,z1=l,z2=mid+;
for (int i=l; i<=r; i++)
{
if (q[i].opt== && q[i].id<=mid) BIT::Change(q[i].y,q[i].del);
if (q[i].opt== && q[i].id>mid) ans[q[i].ID]+=BIT::Query(q[i].y)*q[i].del;
}
for (int i=l; i<=r; i++) if (q[i].opt== && q[i].id<=mid) BIT::Change(q[i].y,-q[i].del);
for (int i=l; i<=r; i++) if (q[i].id<=mid) tmp[z1++]=q[i]; else tmp[z2++]=q[i];
for (int i=l; i<=r; i++) q[i]=tmp[i];
CDQ(l,mid); CDQ(mid+,r);
}
int z,t;
void PreWork(int x1,int y1,int x2,int y2)
{
z++;
t++; q[t].id=t; q[t].ID=z; q[t].x=x1-; q[t].y=y1-; q[t].del=; q[t].opt=;
t++; q[t].id=t; q[t].ID=z; q[t].x=x2; q[t].y=y2; q[t].del=; q[t].opt=;
t++; q[t].id=t; q[t].ID=z; q[t].x=x1-; q[t].y=y2; q[t].del=-; q[t].opt=;
t++; q[t].id=t; q[t].ID=z; q[t].x=x2; q[t].y=y1-; q[t].del=-; q[t].opt=;
}
int main()
{
W=read();
t=; z=;
while ()
{
int opt=read(); if (opt==) break;
if (opt==) {t++; q[t].x=read(),q[t].y=read(),q[t].del=read(),q[t].id=t,q[t].opt=;}
if (opt==) {int x1=read(),y1=read(),x2=read(),y2=read(); PreWork(x1,y1,x2,y2);}
}
sort(q+,q+t+);
// for (int i=1; i<=t; i++) printf("%d %d %d %d %d\n",q[i].id,q[i].opt,q[i].del,q[i].x,q[i].y);
CDQ(,t);
for (int i=; i<=z; i++) printf("%d\n",ans[i]);
return ;
}
【BZOJ-1176&2683】Mokia&简单题 CDQ分治的更多相关文章
- BZOJ 1176/2683 Mokia (三维偏序CDQ+树状数组)
题目大意: 洛谷传送门 三维偏序裸题.. 每次操作都看成一个三元组$<x,y,t>$,表示$x,y$坐标和操作时间$t $ 询问操作拆成$4$个容斥 接下来就是$CDQ$了,外层按t排序, ...
- bzoj 1176: [Balkan2007]Mokia&&2683: 简单题 -- cdq分治
2683: 简单题 Time Limit: 50 Sec Memory Limit: 128 MB Description 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要 ...
- BZOJ 2683: 简单题 [CDQ分治]
同上题 那你为什么又发一个? 因为我用另一种写法又写了一遍... 不用排序,$CDQ$分治的时候归并排序 快了1000ms... #include <iostream> #include ...
- BZOJ 2683 简单题 cdq分治+树状数组
题意:链接 **方法:**cdq分治+树状数组 解析: 首先对于这道题,看了范围之后.二维的数据结构是显然不能过的.于是我们可能会考虑把一维排序之后还有一位上数据结构什么的,然而cdq分治却可以非常好 ...
- BZOJ 2683: 简单题(CDQ 分治)
题面 Time Limit: 50 Sec Memory Limit: 128 MB Description 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作: ...
- BZOJ 2683 简单题 ——CDQ分治
[题目分析] 感觉CDQ分治和整体二分有着很本质的区别. 为什么还有许多人把他们放在一起,也许是因为代码很像吧. CDQ分治最重要的是加入了时间对答案的影响,x,y,t三个条件. 排序解决了x ,分治 ...
- 【BZOJ1176】[Balkan2007]Mokia/【BZOJ2683】简单题 cdq分治
[BZOJ1176][Balkan2007]Mokia Description 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=1600 ...
- 【bzoj1176】[Balkan2007]Mokia/【bzoj2683】简单题 CDQ分治+树状数组
bzoj1176 题目描述 维护一个W*W的矩阵,初始值均为S(题目描述有误,这里的S没有任何作用!).每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数 ...
- bzoj2683简单题 cdq分治
2683: 简单题 Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 1803 Solved: 731[Submit][Status][Discuss] ...
随机推荐
- Apache mod_rewrite规则重写的标志一览
1) R[=code](force redirect) 强制外部重定向 强制在替代字符串加上http://thishost[:thisport]/前缀重定向到外部的URL.如果code不指定,将用缺省 ...
- 030医疗项目-模块三:药品供应商目录模块——供货商药品目录查询功能----------Dao层:基本的查询语句的编写
我们安装显示的要求: 我们能看到显示的目录里面有:供货企业的名字(这个数据来自于供货商的表[usergys]),流水号,通用名,剂型(这些都来自药品信息表),供货的状态(这个呢在gysypml_con ...
- SQL 按特定字段值排序
SQL 按特定字段值排序的代码,有需要的朋友可以参考下. id, name shandong01 name1 shandong02 name2 shandong03 name3 beijing01 n ...
- [转]源代码的管理和发布:以SVN为例
FROM : http://ju.outofmemory.cn/entry/47277 前几天在微博吐槽了SVN的几个不爽的地方:.svn文件满天飞.分支管理的麻烦.不爽一般来说都是有过对比后才有如此 ...
- HDU2444-The Accomodation of Students-判断是否为二分图+ISAP
要先判断是不是二分图.用黑白染色法. 遇到已经染过的跟当前的颜色相同时就说明不是二分图,也即出现了奇环 /*---------------------------------------------- ...
- es6+移动轮播插件
前言:之前赶项目,都是直接用框架,对于touch事件是模拟两可,趁着有心情,用es6写一个原生移动轮播插件. 用了es6的新特性,确实挺爽的,说到es6,就不得不说到babel,博主已经码好了,直接用 ...
- 使用pngquant来压缩png资源缩小apk
最近发现了一个叫做pngquant的工具,可以有效的压缩资源文件中的png文件,从而减小发布的apk的大小.我发现这个工具有两个特点: 1. 真无损,压缩后重新运行了我的app发现是没有任何区别的 2 ...
- parsing XML document from class path resource
遇到问题:parsing XML document from class path resource [spring/resources] 解决方法:项目properties— source—remo ...
- C#链接阿里云KVStore
KVStore的简单介绍 阿里云KVStore兼容Redis.因为KVStore就相当于Redis的服务器端,我们代码只是当作客户端,链接上服务器端就行了,阿里云的KVStore详情文档见,https ...
- Google搜索的几个使用技巧——让你的搜索结果更准确
对于软件开发人员来说,不知道的内容在网上搜索是再正常不过的了.今天同事在组内分享了几个谷歌搜索的使用技巧,在此自己总结一下,希望可以帮到更多人. 在此之前先要唠叨几句,什么时候用百度,什么时候用谷歌? ...