bzoj 1176 Mokia(CDQ分治,BIT)
【题目链接】
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=96974
【题意】
定义查询操作与修改操作:1 x y z 为将格子(x,y)修改为z;2 x1 y1 x2 y2为查询以(x1,y1)为左上(x2,y2)为右下的子矩阵之和。
【思路】
cdq分治。
矩阵初始值都为s,所以先不考虑。
首先明确每一个修改操作都互不影响。然后把每一个对子矩阵的询问操作差分为对四个点的“前缀和”操作。
先把所有的操作按照x升序排列。进行cdq分治。
定义solve(l,r)为解决查询顺序在l,r区间内的操作,且在solve结束后保证区间按照x的递增排列。
1) 将区间按照查询先后顺序重排
2) Solve(l,mid)
3) 计算左区间对右区间的贡献。这时候左区间是按照x升序排列的,右区间是按照查询先后排列的,这样正好既可以保证求贡献时左区间x的单调与递归右区间时右区间内所有的查询都在。对于右区间的i,将左区间内x所有小于它的加入BIT,维护区间和,如果i是询问则查询BIT中所有y小于它的z之和。
4) Solve(mid+1,r)
5) 恢复区间,按照x升序排列
最后答案加上矩阵的s即可。
BIT的清理也可通过加时间戳的方式做到。
【代码】
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; const int N = *1e6+;
const int inf = 1e9+; int n,sz,s,w;
int C[N],flag[N],T,tmp[N]; struct Node {
int x,y,z,pos,ans;
bool operator<(const Node& rhs) const{
return x<rhs.x;
}
Node(int x=,int y=,int z=) {
this->x=x,this->y=y,this->z=z;
pos=sz; ans=;
}
}q[N],t[N];
bool cmp(const Node& x,const Node& y)
{
return x.pos<y.pos;
} void add(int x,int v)
{
for(;x<=w;x+=x&-x)
if(flag[x]!=T) flag[x]=T,C[x]=v;
else C[x]+=v;
}
int query(int x)
{
int res=;
for(;x;x-=x&-x)
if(flag[x]==T) res+=C[x];
return res;
} void solve(int l,int r)
{
if(l==r) return ;
int mid=(l+r)>>;
int l1=l,l2=mid+,i,j;
for(i=l;i<=r;i++) {
if(q[i].pos<=mid) t[l1++]=q[i];
else t[l2++]=q[i];
}
memcpy(q+l,t+l,sizeof(q[])*(r-l+));
solve(l,mid);
j=l; T++;
for(i=mid+;i<=r;i++) {
for(;j<=mid&&q[j].x<=q[i].x;j++)
if(q[j].z!=-inf) add(q[j].y,q[j].z);
if(q[i].z==-inf) q[i].ans+=query(q[i].y);
}
solve(mid+,r);
l1=l,l2=mid+; int now=l;
while(l1<=mid||l2<=r) {
if(l2>r||l1<=mid&&q[l1]<q[l2]) t[now++]=q[l1++];
else t[now++]=q[l2++];
}
memcpy(q+l,t+l,sizeof(q[])*(r-l+));
} void read(int &x)
{
char c=getchar(); x=;int f=;
while(!isdigit(c)){ if(c=='-')f=-; c=getchar(); }
while(isdigit(c)) x=x*+c-'' , c=getchar();
x*=f;
} int main()
{
read(s),read(w);
int op,x1,y1,x2,y2,z;
while(read(op),op!=)
{
if(op==) {
read(x1),read(y1),read(z);
q[++sz]=(Node){x1,y1,z};
} else {
read(x1),read(y1),read(x2),read(y2);
q[++sz]=Node(x1-,y1-,-inf);
tmp[sz]=abs(x1-x2+)*abs(y1-y2+)*s;
q[++sz]=Node(x1-,y2,-inf);
q[++sz]=Node(x2,y1-,-inf);
q[++sz]=Node(x2,y2,-inf);
}
}
sort(q+,q+sz+);
solve(,sz);
sort(q+,q+sz+,cmp);
for(int i=;i<=sz;i++) if(q[i].z==-inf) {
int ans=tmp[i];
ans+=q[i++].ans;
ans-=q[i++].ans;
ans-=q[i++].ans;
ans+=q[i++].ans;
i--;
printf("%d\n",ans);
}
return ;
}
ps:鄙人并非权限汪,如代码不能AC概不负责 :)
bzoj 1176 Mokia(CDQ分治,BIT)的更多相关文章
- BZOJ 1176 Mokia CDQ分治+树状数组
1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1854 Solved: 821[Submit][St ...
- [bzoj] 1176 Mokia || CDQ分治
原题 给出W×W的矩阵(S没有用,题目有误),给出无限次操作,每次操作的含义为: 输入1:你需要把(x,y)(第x行第y列)的格子权值增加a 输入2:你需要求出以左下角为(x1,y1),右上角为(x2 ...
- [BZOJ 3456]城市规划(cdq分治+FFT)
[BZOJ 3456]城市规划(cdq分治+FFT) 题面 求有标号n个点无向连通图数目. 分析 设\(f(i)\)表示\(i\)个点组成的无向连通图数量,\(g(i)\)表示\(i\)个点的图的数量 ...
- [BZOJ 2989]数列(CDQ 分治+曼哈顿距离与切比雪夫距离的转化)
[BZOJ 2989]数列(CDQ 分治) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]| ...
- BZOJ 1176: [Balkan2007]Mokia( CDQ分治 + 树状数组 )
考虑cdq分治, 对于[l, r)递归[l, m), [m, r); 然后计算[l, m)的操作对[m, r)中询问的影响就可以了. 具体就是差分答案+排序+离散化然后树状数组维护.操作数为M的话时间 ...
- BZOJ 1176[Balkan2007]Mokia(CDQ分治)
1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 3381 Solved: 1520[Submit][S ...
- BZOJ 1176: [Balkan2007]Mokia [CDQ分治]
题意: 有一个n * n的棋盘,每个格子内有一个数,初始的时候全部为0.现在要求维护两种操作: 1)Add:将格子(x, y)内的数加上A. 2)Query:询问矩阵(x0, y0, x1, y1)内 ...
- bzoj 3262 陌上花开 - CDQ分治 - 树状数组
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
- bzoj 4237 稻草人 - CDQ分治 - 单调栈
题目传送门 传送点I 传送点II 题目大意 平面上有$n$个点.问存在多少个矩形使得只有左下角和右上角有点. 考虑枚举左下角这个点.然后看一下是个什么情况: 嗯对,是个单调栈.但不可能暴力去求每个点右 ...
随机推荐
- 手工、工具分别实现cookie注入
最开始的判断access类型的网站注入点可以用“1 and 1=1”来判断. 不过现在的网站基本上被挡住了.之后呢,可以考虑cookie注入. Dim Tc_Post,Tc_Get,Tc_In,Tc_ ...
- Data transfer object
Data transfer object (DTO) is a design pattern used to transfer data between software application su ...
- 如何在eclipse里使用git
新版都自带git插件了.在项目上右键,选team,选share project,再选择git就可以了. 如果在本地使用git比较简单.如果要多人共享的使用git,那么需要专门的服务器,并提供ssh,这 ...
- MVC开发过程中的疑难杂症
MVC使用客户端验证 <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type=& ...
- 吐槽C++
个人感觉,在c++ 道路的学习路上,遇到很多的坎坷,现在回想起来,最关键一点就是 c++知识点繁杂很多,教科书很多知识点都没有提到. 但是在实际工作中,这些没有提到的知识点,却又经常会用到(或者看开源 ...
- CURL 多线程问题
http://blog.csdn.net/wslz2001/article/details/12117127 默认情况下libcurl完成一个任务以后,出于重用连接的考虑不会马上关闭 如果没有新的TC ...
- ArcGIS学习记录—KMZ KML与SHP文件互相转换
1.在google earth中绘制边界 工具栏中选择"Add Polygon".随意绘制一个多边形. 右击添加的图层名(左侧)保存位置为,选择保存为kmz或kml文件. ...
- iOS(Swift) TextField限制输入文本的长度(不是字数)
最近做项目有一个特殊需求,就是需要限制一个TextField的输入文本的长度在一定范围内(注意,不是字数),上网查了一圈没有找到类似文章,这里把我的方法写进来,mark一下: 1.对TextField ...
- C++内存中的封装、继承、多态(下)
上篇讲述了内存中的封装模型,下篇我们讲述一下继承和多态. 二.继承与多态情况下的内存布局 由于继承下的内存布局以及构造过程很多书籍都讲得比较详细,所以这里不细讲.重点讲多态. 继承有以下这几种情况: ...
- 关于捕获键盘信息的processDialogkey方法2--具体应用
自定义控件里的keydown方法无法捕获所有的按键消息的处理方法1(自定义控件里的keydown方法无法获取的键值如上下左右键等) 处理办法具体如下: 1.首先在自定义控件UserControl1中重 ...