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$个点.问存在多少个矩形使得只有左下角和右上角有点. 考虑枚举左下角这个点.然后看一下是个什么情况: 嗯对,是个单调栈.但不可能暴力去求每个点右 ...
随机推荐
- [百度]数组A中任意两个相邻元素大小相差1,在其中查找某个数
一.问题来源及描述 今天看了July的微博,发现了七月问题,有这个题,挺有意思的. 数组A中任意两个相邻元素大小相差1,现给定这样的数组A和目标整数t,找出t在数组A中的位置.如数组:[1,2,3,4 ...
- API HOOK
API HOOK技术是一种用于改变API执行结果的技术,Microsoft 自身也在Windows操作系统里面使用了这个技术,如Windows兼容模式等. API HOOK 技术并不是计算机病毒专有技 ...
- DJANGO的ORM的Q查询作多字段外键的模糊查询样码
工作中用到的,存照一下. from django.db.models import Q if self.kwargs.has_key('search_pk'): search_pk = self.kw ...
- HDU4602+推导公式
手动列出前5项 可发现规律 /* 推导公式 a[n] = 2^(n-1) + (n-2)*2^(n-3) */ #include<stdio.h> #include<math.h&g ...
- mysql查看表的结构
①mysql > show create table 表名; ②mysql > desc 表名; ③mysql > describe 表名;
- json中jobject
Json.net codeplex :http://www.codeplex.com/Json 原本感觉Newtonsoft.Json和.net自己的JavaScriptSerializer相差无几, ...
- ASP.NET 访问 MySql
1. 首先需要安装mysql, 脚本之家下载地址: http://www.jb51.net/softs/2193.html 或者去mysql.com官网都可以,一路next,安装好后,有个简单配置,提 ...
- jquery ajax 访问webServer的xml文件
最近项目中要使用到通过ajax访问webServer的xml文件,通过下面的方式可以直接访问webServer的xml文件,不需要在web.xml中进行任何配置.它的返回参数就是服务器上的xml文件. ...
- (转)Android系统自带样式(@android:style/)
在AndroidManifest.xml文件的activity中配置 1.android:theme="@android:style/Theme" 默认状态,即如果theme这里不 ...
- javascript高级程序设计读书笔记
第2章 在html中使用javascript 一般都会把js引用文件放在</body>前面,而不是放在<head>里, 目的是最后读取js文件以提高网页载入速度. 引用js文 ...