[BZOJ2639]矩形计算

题目大意:

给定一个\(n\times m(n,m\le200)\)的矩阵。\(q(q\le10^5)\)次询问,每次询问一个子矩阵中所有数字出现次数的平方和。

思路:

二维莫队。

源代码:

#include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
#define y1 f2s3D3YjsPPh2TRa4GJVf
inline int getint() {
register char ch;
register bool neg=false;
while(!isdigit(ch=getchar())) neg|=ch=='-';
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return neg?-x:x;
}
const int N=201,TOT=40001,Q=1e5;
int a[N][N],tot,tmp[TOT],bel[N],block,sum,cnt[TOT];
struct Query {
int x1,y1,x2,y2,id;
bool operator < (const Query &rhs) const {
if(bel[x1]!=bel[rhs.x1]) return x1<rhs.x1;
if(bel[y1]!=bel[rhs.y1]) return y1<rhs.y1;
if(bel[x2]!=bel[rhs.x2]) return x2<rhs.x2;
return y2<rhs.y2;
}
};
Query q[Q];
int ans[Q];
int x1,y1,x2,y2;
inline int sqr(const int &x) {
return x*x;
}
inline void mdy_x(const int &x,const int &t) {
for(register int i=y1;i<=y2;i++) {
sum-=sqr(cnt[a[x][i]]);
cnt[a[x][i]]+=t;
sum+=sqr(cnt[a[x][i]]);
}
}
inline void mdy_y(const int &y,const int &t) {
for(register int i=x1;i<=x2;i++) {
sum-=sqr(cnt[a[i][y]]);
cnt[a[i][y]]+=t;
sum+=sqr(cnt[a[i][y]]);
}
}
int main() {
block=12;
const int n=getint(),m=getint();
for(register int i=1;i<=n||i<=m;i++) {
bel[i]=i/block;
}
for(register int i=1;i<=n;i++) {
for(register int j=1;j<=m;j++) {
a[i][j]=getint();
tmp[++tot]=a[i][j];
}
}
std::sort(&tmp[1],&tmp[tot]+1);
tot=std::unique(&tmp[1],&tmp[tot]+1)-tmp-1;
for(register int i=1;i<=n;i++) {
for(register int j=1;j<=m;j++) {
a[i][j]=std::lower_bound(&tmp[1],&tmp[tot]+1,a[i][j])-tmp;
}
}
const int c=getint();
for(register int i=0;i<c;i++) {
int x1=getint(),y1=getint(),x2=getint(),y2=getint();
if(x1>x2) std::swap(x1,x2);
if(y1>y2) std::swap(y1,y2);
q[i]=(Query){x1,y1,x2,y2,i};
}
std::sort(&q[0],&q[c]);
x1=1,y1=1,x2=0,y2=0;
for(register int i=0;i<c;i++) {
while(x1>q[i].x1) mdy_x(--x1,1);
while(x2<q[i].x2) mdy_x(++x2,1);
while(x1<q[i].x1) mdy_x(x1++,-1);
while(x2>q[i].x2) mdy_x(x2--,-1);
while(y1>q[i].y1) mdy_y(--y1,1);
while(y2<q[i].y2) mdy_y(++y2,1);
while(y1<q[i].y1) mdy_y(y1++,-1);
while(y2>q[i].y2) mdy_y(y2--,-1);
ans[q[i].id]=sum;
}
for(register int i=0;i<c;i++) {
printf("%d\n",ans[i]);
}
return 0;
}

最新文章

  1. 15个优秀的 Material Design(材料设计)案例
  2. Gulp实现web服务器
  3. 【转】关于KDD Cup '99 数据集的警告,希望从事相关工作的伙伴注意
  4. 【新产品发布】《GM1001 4~20mA 高精度电流采集模块》
  5. Map学习
  6. mysql装载本地文件及模式匹配
  7. Python Socket,How to Create Socket Cilent? - 网络编程实例
  8. VS2008 error C2470
  9. 正则去掉html标签
  10. poj 2540 Hotter Colder 切割多边形
  11. cli/php.ini和fpm/php.ini的区别
  12. 编程语言 : Java的动态Web解决方案泛谈
  13. Screen命令安装使用教程
  14. www-authenticate与BASE-64认证技术
  15. 关于JAVA中异常处理的简单阐释.
  16. WebStorm出现中文乱码解决代码
  17. crontab的笔试题随想
  18. Django-CSRF,AJAX,FORM
  19. JPA Example 基本使用使用实例
  20. mssql sql server 其它系统函数 parsename 点语法字符串分割函数应用简介

热门文章

  1. L0/L1/L2范数(转载)
  2. UML和模式应用5:细化阶段(8)---逻辑架构和UML包图
  3. 在Asp.Net Core中使用中间件保护非公开文件
  4. ubuntu 下抓包
  5. Go语言规格说明书 之 结构体类型(Struct types)
  6. 自适应电脑、手机和iPad的网页设计方法
  7. vue路径优化之resolve
  8. tcpdump使用示例
  9. cf1020c 瞎搞
  10. LINQ学习之旅(五)