1176: [Balkan2007]Mokia

Time Limit: 30 Sec   Memory Limit: 162 MB
Submit: 1683   Solved: 732
[ Submit][ Status][ Discuss]

Description

维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000.

Input

第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小

接下来每行为一下三种输入之一(不包含引号):

"1 x y a"

"2 x1 y1 x2 y2"

"3"

输入1:你需要把(x,y)(第x行第y列)的格子权值增加a

输入2:你需要求出以左上角为(x1,y1),右下角为(x2,y2)的矩阵内所有格子的权值和,并输出

输入3:表示输入结束

Output

对于每个输入2,输出一行,即输入2的答案

Sample Input

0 4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3

Sample Output

3
5

HINT

保证答案不会超过int范围

CDQ分治+树状数组

对于一个矩形的询问,根据容斥原理可以拆成四个询问,然后将询问和修改一起CDQ分治。

每一层处理[l,mid]对[mid+1,r]答案的影响,先保证x有序,然后树状数组维护就可以了。

最开始的sort保证了每一层处理时x都有序。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define maxn 200005
using namespace std;
int s,w,n,cnt;
int ans[10005],sum[2000005];
struct data{int x,y,z,pos,id;}a[maxn],b[maxn];
inline int read()
{int x=0,f=1;char ch=getchar();while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
inline bool cmp(data a,data b)
{if (a.x==b.x&&a.y==b.y) return a.pos<b.pos;else if (a.x==b.x) return a.y<b.y;else return a.x<b.x;
}
inline void add(int x,int v)
{for(int i=x;i<=w;i+=i&(-i)) sum[i]+=v;
}
inline int query(int x)
{int ret=0;for(int i=x;i;i-=i&(-i)) ret+=sum[i];return ret;
}
inline void solve(int l,int r)
{if (l==r) return;int mid=(l+r)>>1,l1=l,l2=mid+1;
//  memset(sum,0,sizeof(sum));//这样写会TLE F(i,l,r){if (a[i].id<=mid&&!a[i].pos) add(a[i].y,a[i].z);if (a[i].id>mid&&a[i].pos) ans[a[i].pos]+=query(a[i].y)*a[i].z;}F(i,l,r) if (a[i].id<=mid&&!a[i].pos) add(a[i].y,-a[i].z);//如果把这句话替换成memset会TLE F(i,l,r){if (a[i].id<=mid) b[l1++]=a[i];else b[l2++]=a[i];}F(i,l,r) a[i]=b[i];solve(l,mid);solve(mid+1,r);
}
int main()
{s=read();w=read();for(;;){int opt=read();if (opt==1){int x=read(),y=read(),z=read();n++;a[n]=(data){x,y,z,0,n};}else if (opt==2){int x1=read()-1,y1=read()-1,x2=read(),y2=read();ans[++cnt]=(x2-x1)*(y2-y1)*s;n++;a[n]=(data){x1,y1,1,cnt,n};n++;a[n]=(data){x1,y2,-1,cnt,n};n++;a[n]=(data){x2,y1,-1,cnt,n};n++;a[n]=(data){x2,y2,1,cnt,n};}else break;}sort(a+1,a+n+1,cmp);solve(1,n);F(i,1,cnt) printf("%d\n",ans[i]);return 0;
}

还有一种写法是最开始不sort,即最初状态是按照时间从小到大。

每次分治的时候先分治处理两个子区间,然后按照横坐标归并排序,最后计算答案。

两个算法复杂度都是O(n*logn)。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define maxn 200005
using namespace std;
int s,w,n,cnt;
int ans[10005],sum[2000005];
struct data{int x,y,z,pos,id;}a[maxn],b[maxn];
inline int read()
{int x=0,f=1;char ch=getchar();while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
inline bool cmp(data a,data b)
{return a.x!=b.x?a.x<b.x:a.id<b.id;
}
inline void add(int x,int v)
{for(int i=x;i<=w;i+=i&(-i)) sum[i]+=v;
}
inline int query(int x)
{int ret=0;for(int i=x;i;i-=i&(-i)) ret+=sum[i];return ret;
}
inline void solve(int l,int r)
{if (l==r) return;int mid=(l+r)>>1,l1=l,l2=mid+1,tmp=l;solve(l,mid);solve(mid+1,r);while (l1<=mid&&l2<=r) b[tmp++]=cmp(a[l1],a[l2])?a[l1++]:a[l2++];while (l1<=mid) b[tmp++]=a[l1++];while (l2<=r) b[tmp++]=a[l2++];F(i,l,r) a[i]=b[i];F(i,l,r){if (a[i].id<=mid&&!a[i].pos) add(a[i].y,a[i].z);if (a[i].id>mid&&a[i].pos) ans[a[i].pos]+=a[i].z*query(a[i].y);}F(i,l,r) if (a[i].id<=mid&&!a[i].pos) add(a[i].y,-a[i].z);
}
int main()
{s=read();w=read();for(;;){int opt=read();if (opt==1){int x=read(),y=read(),z=read();n++;a[n]=(data){x,y,z,0,n};}else if (opt==2){int x1=read()-1,y1=read()-1,x2=read(),y2=read();ans[++cnt]=(x2-x1)*(y2-y1)*s;n++;a[n]=(data){x1,y1,1,cnt,n};n++;a[n]=(data){x1,y2,-1,cnt,n};n++;a[n]=(data){x2,y1,-1,cnt,n};n++;a[n]=(data){x2,y2,1,cnt,n};}else break;}solve(1,n);F(i,1,cnt) printf("%d\n",ans[i]);return 0;
}

bzoj1176【Balkan2007】Mokia相关推荐

  1. 【BOI2007】Mokia 摩基亚

    传送门 CDQ分治板子题 其实和陌上花开差不多 把时间. l . r l.r l.r看成三个维度 像二维树状数组统计一样,把每一个询问拆成四块前缀和相减 然后统计答案的时候容斥一下 那么现在需要考虑的 ...

  2. 【教程】简易CDQ分治教程学习笔记

    前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦!       CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...

  3. 【CentOS】利用Kubeadm部署Kubernetes (K8s)

    [CentOS]利用Kubeadm部署Kubernetes (K8s)[阅读时间:约10分钟] 一.概述 二.系统环境&项目介绍 1.系统环境 2.项目的任务要求 三.具体实验流程 1 系统准 ...

  4. 【Spring】框架简介

    [Spring]框架简介 Spring是什么 Spring是分层的Java SE/EE应用full-stack轻量级开源框架,以IOC(Inverse Of Control:反转控制)和AOP(Asp ...

  5. 【C#】类——里式转换

    类是由面对对象程序设计中产生的,在面向结构的程序设计例如C语言中是没有类这个概念的!C语言中有传值调用和传址调用的两种方式!在c语言中,主方法调用方法,通过传递参数等完成一些操作,其中比较常用的的数据 ...

  6. 【C#】Out与ref是干什么的?

    关于return: 1.最后没有写 return 语句的话,表示程序正常退出 2.不需要返回值时,存在return的作用 例子 void main() {return; //return退出该程序的作 ...

  7. 【软件工程】RUP与软件开发5大模型

    软件开发的5大模型 1.瀑布模型:按照人的思维一步一步的开发下去,如果需求分析得当,每个阶段顺利,结果还不错! 2.快速原型模型:后来人们发现,自己不可能一下子就把所有的需求搞清楚,总是在开发的过程中 ...

  8. 【VB】学生信息管理系统5——数据库代码

    这次学生信息管理系统在代码的理解过程中遇到了一些问题.总结如下: 1. sql server的安装过程各个步骤的意思.在安装SQL Server的时候按照网上的步骤,我觉得这个需要学完整个数据库再返回 ...

  9. 白化(预处理步骤)【转】

    白化(预处理步骤)[转] 介绍 我们已经了解了如何使用PCA降低数据维度.在一些算法中还需要一个与之相关的预处理步骤,这个预处理过程称为白化.举例来说,假设训练数据是图像,由于图像中相邻像素之间具有很 ...

最新文章

  1. 【机器学习】机器学习12个关键经验教训
  2. 【PC工具】几个电脑录屏相关软件,手机投屏电脑,电脑显示手机摄像头图像,必须好用无广告!...
  3. 24-hadoop-hiveserver2jdbc-正则数据导入
  4. 80后,天才程序员, Facebook 第一任 CTO,看看开挂的人生到底有多变态?
  5. C语言学习之求1+2+3+···+100的值
  6. Kafka官方文档翻译——实现
  7. ASP与ActiveX控件交互实战(一)
  8. 修改linq结果集_linq 查询的结果会开辟新的内存吗?
  9. Can not find the tag library descriptor for http://java.sun.com/jsp/jst1/core
  10. ZZULIOJ 1882: 蛤玮的魔法【数学】
  11. Could not connect to appstore: cURL error 28: Operation timed out after 60000 milliseconds with
  12. CodeCademy | Python | 6. Pyglatin
  13. 将1自动补位为01_自动补位为辅助后游戏就输了一半?那是你不懂辅助的正确打开方式...
  14. 【uni-app】解决iPhone X “刘海屏”兼容性问题
  15. 如何防止自己的电脑成为肉鸡?
  16. Beginning Auto Layout Tutorial in iOS 7: Part 2
  17. python实现去重_Python列表去重的4种实现方法
  18. 【曹工杂谈】Maven底层容器Plexus Container的前世今生,一代芳华终落幕
  19. ARCGIS10.2加载天地图不显示
  20. Arduino安装esp32 SDK(Windows)问题:AzureIoT: no headers files解决

热门文章

  1. cnn 实现图片识别
  2. C++代码静态分析与优化(5)_flawfinder
  3. 实战篇:GBase 8a MPP Cluster 安装部署过程
  4. 抓娃娃机爪不动怎么办_抓娃娃机出故障了要怎么维修
  5. 完美解决vs编译器scanf报错问题
  6. RNA二级结构在 siRNA设计中的应用
  7. 《Java编程的逻辑》阅后心得
  8. python基础---布尔表达式
  9. linux中重定向命令,LINUX 重定向命令
  10. 学到中年的python学习笔记06--面向对象基础编程