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$个点.问存在多少个矩形使得只有左下角和右上角有点. 考虑枚举左下角这个点.然后看一下是个什么情况: 嗯对,是个单调栈.但不可能暴力去求每个点右 ...
随机推荐
- POJ - 1741 Tree
DescriptionGive a tree with n vertices,each edge has a length(positive integer less than 1001).Defin ...
- eval()字符串转成对象
var s = "{a:1,b:2}"; console.log(typeof s); s = eval("(" + s + ")"); c ...
- BZOJ 3288 Mato矩阵 解题报告
这个题好神呀..Orz taorunz 有一个结论,这个结论感觉很优美: $$ans = \prod_{i=1}^{n}\varphi(i)$$ 至于为什么呢,大概是这样子的: 对于每个数字 $x$, ...
- [转载]Jquery Form插件表单参数
表单插件API提供了几个方法,让你轻松管理表单数据和进行表单提交. ajaxForm增 加所有需要的事件监听器,为AJAX提交表单做好准备.ajaxForm不能提交表单.在document的ready ...
- [转载]js 遍历数组对象
有一个JSON数组如下 all = {"error":0,"content":[{"name":"北京","v ...
- POJ-1088 滑雪 (包含部分自用测试数据)
这题最简单的想法是深搜+记录,由于数据量比较小.这么做可以AC.如果在h大的情况下这种递归方法总会有一些问题. 如果转换一下,这个可以使用递推来解决,先对高度进行由低到高的排序,然后顺序对这些高度计算 ...
- Servlet课程0424(二) 通过继承GenericServlet来开发Servlet
//这是第二种开发servlet的方法(继承GernericServlet) package com.tsinghua; import javax.servlet.GenericServlet; im ...
- 隐马尔科夫模型 介绍 HMM python代码
#HMM Forward algorithm #input Matrix A,B vector pi import numpy as np A=np.array([[0.5,0.2,0.3],[0.3 ...
- D3D游戏编程系列(一):DXLib的介绍
这篇文章里我准备向大家介绍下我封装的一个基础D3D库:DXLib.有了这样一个类库,可以减少很多无用功以及繁琐的工作,使我们的效率大大提高. DXLib.h #define DIRECTINPUT_V ...
- Magic skills of vim from zhihu
https://www.zhihu.com/question/27478597 插入模式下ctrl-y,重复当前光标上一行的字符 gd 高亮当前词 cc 删除当前行并插入 “.” 这个 mark 代表 ...