二维莫队,按x,y坐标一起分块.(x,y)的所属的块为 x/sq(n)*sq(m) + y/sq(m)
排序时按照(左下点所在块,右上点的标号)排序
排序后 先得出一个询问的答案,然后利用上一个询问的矩形与当前矩形位置关系更新答案
转移真的麻烦。。为了避免算重 一定要加个vis[][]
//4432kb 13600ms
#include <cmath>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=205,M=1e5+5;
int n,m,Q,szX,szY,A[N][N],ref[N*N],tm[N*N],bel[N][N],idv[N][N];
LL Ans[M],Now;
bool vis[N][N];
struct Ask
{
int x1,y1,x2,y2,id;
inline bool operator <(const Ask &a)const{
return bel[x1][y1]==bel[a.x1][a.y1]?idv[x2][y2]<idv[a.x2][a.y2]:bel[x1][y1]<bel[a.x1][a.y1];
}
}q[M];
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
int Find(int x,int r)
{
int l=1,mid;
while(l<r)
if(ref[mid=l+r>>1]>=x) r=mid;
else l=mid+1;
return l;
}
void Discrete()
{
int tot=0,cnt=1;
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
ref[idv[i][j]=++tot]=A[i][j]=read();
std::sort(ref+1,ref+1+tot);
for(int i=2; i<=tot; ++i)
if(ref[i]!=ref[i-1]) ref[++cnt]=ref[i];
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
A[i][j]=Find(A[i][j],cnt);
}
inline void add(int i,int j){
if(!vis[i][j]) vis[i][j]=1, Now+=2*(tm[A[i][j]]++)+1;
}
inline void subd(int i,int j){
if(vis[i][j]) vis[i][j]=0, Now-=2*(--tm[A[i][j]])+1;
}
void Add(int x1,int x2,int y1,int y2)
{
for(int i=x1; i<=x2; ++i)
for(int j=y1; j<=y2; ++j) add(i,j);
}
void Subd(int x1,int x2,int y1,int y2)
{
for(int i=x1; i<=x2; ++i)
for(int j=y1; j<=y2; ++j) subd(i,j);
}
void Change(int l,int n)
{//now位于las的左下方 左上方 被包含 都是可能的
int t;
t=std::min(q[l].x1-1,q[n].x2), Add(q[n].x1,t,q[n].y1,q[n].y2);
t=std::min(q[l].y1-1,q[n].y2), Add(q[n].x1,q[n].x2,q[n].y1,t);
t=std::max(q[l].x2+1,q[n].x1), Add(t,q[n].x2,q[n].y1,q[n].y2);
t=std::max(q[l].y2+1,q[n].y1), Add(q[n].x1,q[n].x2,t,q[n].y2);
t=std::min(q[l].x2,q[n].x1-1), Subd(q[l].x1,t,q[l].y1,q[l].y2);
t=std::min(q[l].y2,q[n].y1-1), Subd(q[l].x1,q[l].x2,q[l].y1,t);
t=std::max(q[l].y1,q[n].y2+1), Subd(q[l].x1,q[l].x2,t,q[l].y2);
t=std::max(q[l].x1,q[n].x2+1), Subd(t,q[l].x2,q[l].y1,q[l].y2);
}
int main()
{
n=read(),m=read(); szX=sqrt(n),szY=sqrt(m);
Discrete();
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
bel[i][j]=(i-1)/szX*szY+(j-1)/szY;
// for(int i=1; i<=n; ++i,putchar('\n'))
// for(int j=1; j<=m; ++j) printf("%d ",bel[i][j]);
Q=read();
for(int i=1; i<=Q; ++i)
{
q[i].x1=read(),q[i].y1=read(),q[i].x2=read(),q[i].y2=read();
if(q[i].x1>q[i].x2) std::swap(q[i].x1,q[i].x2);//将(x1,y1)设为矩形左下角
if(q[i].y1>q[i].y2) std::swap(q[i].y1,q[i].y2);
q[i].id=i;
}
std::sort(q+1,q+1+Q);
Add(q[1].x1,q[1].x2,q[1].y1,q[1].y2);
Ans[q[1].id]=Now;
for(int i=2; i<=Q; ++i)
Change(i-1,i), Ans[q[i].id]=Now;
for(int i=1; i<=Q; ++i) printf("%lld\n",Ans[i]);
return 0;
}
BZOJ.2639.矩形计算(二维莫队)的更多相关文章
-
【二维莫队】【二维分块】bzoj2639 矩形计算
<法一>二维莫队,对n和m分别分块后,对块从上到下从左到右依次编号,询问以左上角所在块编号为第一关键字,以右下角标号为第二关键字排序,转移时非常厉害. O(q*n*sqrt(n)). #i ...
-
[CSP-S模拟测试]:蔬菜(二维莫队)
题目描述 小$C$在家中开垦了一块菜地,可以抽象成一个$r\times c$大小的矩形区域,菜地的每个位置都种着一种蔬菜.秋天到了,小$C$家的菜地丰收了. 小$C$拟定了$q$种采摘蔬菜的计划,计划 ...
-
csp-s模拟测试50(9.22)「施工(单调栈优化DP)」&#183;「蔬菜(二维莫队???)」&#183;「联盟(树上直径)」
改了两天,终于将T1,T3毒瘤题改完了... T1 施工(单调栈优化DP) 考场上只想到了n*hmaxn*hmaxn的DP,用线段树优化一下变成n*hmaxn*log但显然不是正解 正解是很**的单调 ...
-
【Unity3D】计算二维向量夹角(-180到180)
在Unity3D中,有时候我们需要计算二维向量的夹角.二维向量夹角一般在0~180度之前,可以直接调用Vector2.Angle(Vector2 from, Vector2 to)来计算. 但是在有些 ...
-
PHP计算二维数组指定元素的和
array_sum(array_column($arr, 'num')); //计算二维数组指定元素的和 $arr = [ [ 'id'=>1, 'num'=>3, ], [ 'id'=& ...
-
bzoj 2038 小z的袜子 莫队例题
莫队,利用可以快速地通过一个问题的答案得到另一问题的答案这一特性,合理地组织问题的求解顺序,将已解决的问题帮助解决当前问题,来优化时间复杂度. 典型用法:处理静态(无修改)离线区间查询问题. 线段树也 ...
-
bzoj 2038 小Z的袜子 莫队算法
题意 给你一个长度序列,有多组询问,每次询问(l,r)任选两个数相同的概率.n <= 50000,数小于等于n. 莫队算法裸题. 莫队算法:将序列分为根号n段,将询问排序,以L所在的块为第一关键 ...
-
BZOJ 4939: [Ynoi2016]掉进兔子洞(莫队+bitset)
传送门 解题思路 刚开始想到了莫队+\(bitset\)去维护信息,结果发现空间不太够..试了各种奇技淫巧都\(MLE\),最后\(\%\)了发题解发现似乎可以分段做..这道题做法具体来说就是开\(3 ...
-
BZOJ 3289 Mato的文件管理(莫队+离散化求逆序数)
3289: Mato的文件管理 Time Limit: 40 Sec Memory Limit: 128 MB Submit: 2171 Solved: 891 [Submit][Status][ ...
随机推荐
-
window对象的属性及事件。
不同的运行环境有不同的“顶层对象”,而在浏览器的环境中,顶层对象就是window对象.window就是指当前的浏览器窗口. 例:var a = 1: window.a; //1 1.window对象的 ...
-
Laravel5设计json api时候的一些道道
对于返回数据格式没规整的问题 在开发api的时候,这个问题是和客户端交涉最多的问题,比如一个user结构,返回的字段原本是个user_name的,它应该是string类型.但是呢,由于数据库设计这个字 ...
-
PHP魔术方法使用总结
魔术方法是PHP面向对象中特有的特性.它们在特定的情况下被触发,都是以双下划线开头,你可以把它们理解为钩子,利用模式方法可以轻松实现PHP面向对象中重载(Overloading即动态创建类属性和方法) ...
-
[转]Ubuntu中apt与apt-get命令的区别
转载于https://www.sysgeek.cn/apt-vs-apt-get/ Ubuntu 16.04 发布时,一个引人注目的新特性便是 apt 命令的引入.其实早在 2014 年,apt 命令 ...
-
Mybatis的针对于同一个有自己父类或子类的递归查询 (如商品分类)
1.pojo代码 private Integer categoryId; private Integer superId; private String name; private Byte leve ...
-
使用AJAX技术发送异步请求,HTTP服务端推送
使用AJAX技术发送异步请求 什么是AJAX AJAX指一步Javascript和XML(Asynchronous JavaScript And XML),它是一些列技术的组合,简单来说AJAX基于X ...
-
tomcat配置问题:访问http://localhost:8080/ 遇到 Access Error: 404
win7: 8080端口已经被其他应用使用,比如nixxxxxxxxxxxxx When I had an error Access Error: 404 -- Not Found I fixed i ...
-
微擎app端上传图片后删除不了图片
相信在微擎开发的哥们都知道, 微擎在手册方面还是有点坑的,根本不让人活啊.没办法, 开发时, 只能自己看着源码来搞>>>> 好, 不多说了. 现在来看一个坑 ..直接上代码\ ...
-
获取当前View
在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById().不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例 ...
-
iframe加载的文档高度
var clientHeight = $("#iframe").contents().find("body").height();