您的位置:首页 > 其它

2639: 矩形计算|二维莫队

2016-03-14 21:27 381 查看
被刷了一天题现在整个人处于SB状态。。

二维莫队就是直接把横纵坐标都分块,具体的做法就是坐标(x,y)(x,y)属于块⌊x−1n√⌋∗m−−√+⌊y−1m√⌋\lfloor\frac{x-1}{\sqrt{n}}\rfloor*\sqrt{m}+\lfloor\frac{y-1}{\sqrt{m}}\rfloor,然后就开始像一维的那样暴力维护。

两个矩形相互转移的的时候有点乱,算是二维莫队的最难写的地方了

#include<set>
#include<map>
#include<ctime>
#include<queue>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
int sc()
{
int i=0,f=1; char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
return i*f;
}
struct W{
int x,y,v;
}t[40040];
struct Q{
int x1,x2,y1,y2,p;
}q[100010];
bool vis[202][202];
int a[222][222],bl[202][202],Ans[100010],id[202][202],T[40004];
int n,m,tot,mx,bn,bm,ans;
bool cmp(W a,W b){return a.v<b.v;}
bool cmp1(Q a,Q b)
{
return bl[a.x1][a.y1]==bl[b.x1][b.y1]?id[a.x2][a.y2]<id[b.x2][b.y2]:bl[a.x1][a.y1]<bl[b.x1][b.y1];
}
void insert(int x,int y)
{
if(!vis[x][y])
{
vis[x][y]=1;
ans+=2*(T[a[x][y]]++)+1;
}
}
void del(int x,int y)
{
if(vis[x][y])
{
vis[x][y]=0;
ans-=2*(--T[a[x][y]])+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++)
insert(i,j);
}
void DEL(int x1,int x2,int y1,int y2)
{
for(int i=x1;i<=x2;i++)
for(int j=y1;j<=y2;j++)
del(i,j);
}
void change(Q a,Q b)
{
int t;
t=min(a.x1-1,b.x2);ADD(b.x1,t,b.y1,b.y2);
t=max(a.x2+1,b.x1);ADD(t,b.x2,b.y1,b.y2);
t=min(a.y1-1,b.y2);ADD(b.x1,b.x2,b.y1,t);
t=max(a.y2+1,b.y1);ADD(b.x1,b.x2,t,b.y2);

t=min(b.x1-1,a.x2);DEL(a.x1,t,a.y1,a.y2);
t=max(b.x2+1,a.x1);DEL(t,a.x2,a.y1,a.y2);
t=min(b.y1-1,a.y2);DEL(a.x1,a.x2,a.y1,t);
t=max(b.y2+1,a.y1);DEL(a.x1,a.x2,t,a.y2);
}
int main()
{
n=sc(),m=sc();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
id[i][j]=++tot,t[tot].x=i,t[tot].y=j,t[tot].v=sc();
sort(t+1,t+tot+1,cmp);
for(int i=1;i<=tot;i++)
{
if(t[i].v!=t[i-1].v)
a[t[i].x][t[i].y]=++mx;
else a[t[i].x][t[i].y]=mx;
}
bn=sqrt(n),bm=sqrt(m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
bl[i][j]=(i-1)/bn*bm+(j-1)/bm;
int Q=sc();
for(int i=1;i<=Q;i++)
{
q[i].p=i;
q[i].x1=sc(),q[i].y1=sc();
q[i].x2=sc(),q[i].y2=sc();
if(q[i].x1>q[i].x2)swap(q[i].x1,q[i].x2);
if(q[i].y1>q[i].y2)swap(q[i].y1,q[i].y2);
}
sort(q+1,q+Q+1,cmp1);
for(int i=q[1].x1;i<=q[1].x2;i++)
for(int j=q[1].y1;j<=q[1].y2;j++)
insert(i,j);
Ans[q[1].p]=ans;
for(int i=2;i<=Q;i++)
{
change(q[i-1],q[i]);
Ans[q[i].p]=ans;
}
for(int i=1;i<=Q;i++)printf("%d\n",Ans[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: