题目传送门

题解:现在需要维护的每次的询问矩形和前面插入的所有矩形有公共部分的个数。 我们试着直接去维护这个东西, 发现可能的情况太多,不好维护,所以我们维护每次询问的时候在当前矩阵个数下,有多少个矩阵是一定在外面的。对于一个矩阵来说, 我们只需要统计到目前位置, 多少个矩形的下底线 在询问矩形的上底线之上, 这样我们就减去了在询问矩形上方的不重合矩形。 然后我们对矩形的左右下也一样维护这个信息。对于这个操作我们可以用4个树状数组直接去维护这个信息。每个数状数组记录一下每条底线出现的位置。

维护完这个东西之后,我们发现如果一个矩形在询问矩形的左上方, 他会被减去2次,这样就多减了, 我们需要把左上角的矩形个数再加回去。 我们需要 对每个询问矩形来说, 维护出有多少个插入矩形的右下角的端点是在询问矩形的左上角的端点的左上角, 对于这个问题就变成了一个2维偏序问题,我们用cdq去维护这个信息。当然还有其他3个角落,我们也需要对那些角度做一样的操作。最后我们就可以得到答案了。

代码:

 #include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 2e5 + ;
struct Node{
int x1, y1, x2, y2, op, id;
}A[N], B[N];
int xsz, ysz;
int x[N], y[N];
int tmp[N];
int ans[N];
char s[];
struct bit_tree{
int tree[N], tot;
void add(int x, int v){
for(int i = x; i < N; i += i & (-i)){
tree[i] += v;
}
tot += v;
}
int query(int x){
int ret = ;
for(int i = x; i > ; i -= i & (-i)){
ret += tree[i];
}
return ret;
}
void Clear(){
tot = ;
memset(tree, , sizeof(tree));
}
}bit[];
bool cmp1(Node & a, Node & b){
int aop = abs(a.op), bop = abs(b.op);
int ax, bx;
if(aop) ax = a.x2;
else ax = a.x1;
if(bop) bx = b.x2;
else bx = b.x1;
if(ax != bx) return ax < bx;
return aop < bop;
}
bool cmp2(Node & a, Node & b){
int aop = abs(a.op), bop = abs(b.op);
int ax, bx;
if(!aop) ax = a.x2;
else ax = a.x1;
if(!bop) bx = b.x2;
else bx = b.x1;
if(ax != bx) return ax > bx;
return aop < bop;
}
void cdq(int l, int r){
if(l >= r) return ;
int mid = l+r >> ;
cdq(l, mid);
cdq(mid+, r);
int top = ;
for(int i = l; i <= mid; i++)
if(A[i].op) B[++top] = A[i];
for(int i = mid+; i <= r; i++)
if(!A[i].op) B[++top] = A[i];
sort(B+, B++top, cmp1);
for(int i = ; i <= top; i++){
if(B[i].op) {
bit[].add(B[i].y1, B[i].op);
bit[].add(B[i].y2, B[i].op);
}
else {
ans[B[i].id] += bit[].tot - bit[].query(B[i].y2);
ans[B[i].id] += bit[].query(B[i].y1-);
}
}
for(int i = ; i <= top; i++){
if(B[i].op) {
bit[].add(B[i].y1, -B[i].op);
bit[].add(B[i].y2, -B[i].op);
}
}
sort(B+, B++top, cmp2);
for(int i = ; i <= top; i++){
if(B[i].op) {
bit[].add(B[i].y1, B[i].op);
bit[].add(B[i].y2, B[i].op);
}
else {
ans[B[i].id] += bit[].tot - bit[].query(B[i].y2);
ans[B[i].id] += bit[].query(B[i].y1-);
}
}
for(int i = ; i <= top; i++){
if(B[i].op) {
bit[].add(B[i].y1, -B[i].op);
bit[].add(B[i].y2, -B[i].op);
}
}
}
int main(){
int n;
scanf("%d", &n);
int t = , tt = , num = , z;
for(int i = ; i <= n; ++i){
scanf("%s", s);
if(s[] == 'I'){
num++;
scanf("%d%d%d%d", &A[i].x1, &A[i].y1, &A[i].x2, &A[i].y2);
x[++xsz] = A[i].x1; x[++xsz] = A[i].x2;
y[++ysz] = A[i].y1; y[++ysz] = A[i].y2;
A[i].op = ;
tmp[++t] = i;
}
else if(s[] == 'D'){
num--;
scanf("%d", &z);
A[i] = A[tmp[z]];
A[i].op = -;
}
else {
++tt;
scanf("%d%d%d%d", &A[i].x1, &A[i].y1, &A[i].x2, &A[i].y2);
x[++xsz] = A[i].x1; x[++xsz] = A[i].x2;
y[++ysz] = A[i].y1; y[++ysz] = A[i].y2;
A[i].op = ;A[i].id = tt;
ans[tt] = num;
}
}
sort(x+, x+xsz+); sort(y+, y+ysz+);
xsz = unique(x+, x++xsz) - x - ;
ysz = unique(y+, y++ysz) - y - ;
for(int i = ; i <= n; i++){
A[i].x1 = lower_bound(x+, x++xsz, A[i].x1) - x;
A[i].x2 = lower_bound(x+, x++xsz, A[i].x2) - x;
A[i].y1 = lower_bound(y+, y++ysz, A[i].y1) - y;
A[i].y2 = lower_bound(y+, y++ysz, A[i].y2) - y;
if(A[i].op){
bit[].add(A[i].x1, A[i].op);
bit[].add(A[i].x2, A[i].op);
bit[].add(A[i].y1, A[i].op);
bit[].add(A[i].y2, A[i].op);
}
else {
num = ans[A[i].id];
ans[A[i].id] -= num - bit[].query(A[i].x2);
ans[A[i].id] -= bit[].query(A[i].x1-);
ans[A[i].id] -= num - bit[].query(A[i].y2);
ans[A[i].id] -= bit[].query(A[i].y1-);
}
}
for(int i = ; i < ; i++) bit[i].Clear();
cdq(, n);
for(int i = ; i <= tt; i++)
printf("%d\n", ans[i]);
return ;
}

CodeChef - QRECT Rectangle Query CDQ分治的更多相关文章

  1. Codechef SEP14 QRECT cdq分治+线段树

    题意 支持删除矩阵.插入矩阵.查询当前矩阵与之前有多少个矩阵相交 算相交的时候容斥一下:相交矩形数 = 总矩形数-X轴投影不相交的矩形数-Y轴投影不相交的矩形数-XY轴投影下都不相交的矩形数 最后一项 ...

  2. 算法笔记--CDQ分治 && 整体二分

    参考:https://www.luogu.org/blog/Owencodeisking/post-xue-xi-bi-ji-cdq-fen-zhi-hu-zheng-ti-er-fen 前置技能:树 ...

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

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

  4. BZOJ 2683 简单题 ——CDQ分治

    [题目分析] 感觉CDQ分治和整体二分有着很本质的区别. 为什么还有许多人把他们放在一起,也许是因为代码很像吧. CDQ分治最重要的是加入了时间对答案的影响,x,y,t三个条件. 排序解决了x ,分治 ...

  5. 初识CDQ分治

    [BZOJ 1176:单点修改,查询子矩阵和]: 1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 200 ...

  6. BZOJ4170 极光(CDQ分治 或 树套树)

    传送门 BZOJ上的题目没有题面-- [样例输入] 3 5 2 4 3 Query 2 2 Modify 1 3 Query 2 2 Modify 1 2 Query 1 1 [样例输出] 2 3 3 ...

  7. BZOJ2683 简单题(CDQ分治)

    传送门 之前听别人说CDQ分治不难学,今天才知道果真如此.之前一直为自己想不到CDQ的方法二很不爽,今天终于是想出来了一道了,太弱-- cdq分治主要就是把整段区间分成两半,然后用左区间的值去更新右区 ...

  8. 【BZOJ-3262】陌上花开 CDQ分治(3维偏序)

    3262: 陌上花开 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1439  Solved: 648[Submit][Status][Discuss ...

  9. 【BZOJ-1176&2683】Mokia&简单题 CDQ分治

    1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1854  Solved: 821[Submit][St ...

随机推荐

  1. 【Intellij】导入 jar 包

    选中工具栏上"File"--->"Project Structure"--->选择“Libraries”--->点击“+”--->选择自 ...

  2. 【iOS】“找不到使用指定主机名的服务器”

    今天用 Application Loader 提交 APP 的时,遇到了这个奇葩的问题,如下图: 后来换个网络解决了……我也不知道什么原因,就这么奇葩的弄好了……

  3. Tomcat发布War包或者Maven项目

    在tomcat的conf目录下面的server.xml中修改如下: Host name="localhost"  appBase="webapps" unpac ...

  4. Hadoop 系列(三)—— 分布式计算框架 MapReduce

    一.MapReduce概述 Hadoop MapReduce 是一个分布式计算框架,用于编写批处理应用程序.编写好的程序可以提交到 Hadoop 集群上用于并行处理大规模的数据集. MapReduce ...

  5. 【Java例题】6.2 日期类的使用

    2.日期类的使用.显示今天的年月日.时分秒和毫秒数.显示今天是星期几.是今年内的第几天.显示本月共几天,今年是不是闰年.显示两个日期的差,包括年月日.时分秒和毫秒差值. package chapter ...

  6. Java虚拟机学习笔记(二)--- 判断对象是否存活

    Java堆中存放着所有的对象实例,垃圾收集器在堆进行回收之前,需要判断对象是“存活”还是“死亡”(即不可能再被任何途径引用的对象). 最常见的一种判断对象是否存活算法是引用计数算法, 给对象加一个引用 ...

  7. Java中只有值传递,(及值传递与引用传递详解)

    首先呢,我们来说一下值传递与引用传递的区别(这两个玩意儿实在调用函数的时候提到的) 比如说 code( a) code( int a ) code(a)是调用函数,a是我们原本函数的一个值类型,然后使 ...

  8. idea+Spring+Mybatis+jersey+jetty构建一个简单的web项目

    一.先使用idea创建一个maven项目. 二.引入jar包,修改pom.xml <dependencies> <dependency> <groupId>org. ...

  9. SonarQube系列二、分析dotnet core/C#代码

    [前言] 本系列主要讲述sonarqube的安装部署以及如何集成jenkins自动化分析.netcore项目.目录如下: SonarQube系列一.Linux安装与部署 SonarQube系列二.分析 ...

  10. getpost请求案例

    public class MainActivity extends AppCompatActivity { private ListView lv; @Override protected void ...