首先考虑容斥

我们计算出所有没有点在其中的矩形,然后用所有矩形减去这些矩形即可

然后考虑如何计算没有点在其中的矩形

采用扫描线的思想,从上向下一行一行扫,假设我们扫到的行编号是$a$,然后考虑如果左右的列端点是$[l,r]$,那么这一行向上至多能扩展几个矩形呢?

显然,我们要找到区间$[l,r]$中位置最下面的那个点,设其行编号为$w[i]$,那么矩形数量即为$a-w[i]$

画个图理解一下:

很清楚的就能看到,现在扫到的是红色的$a$,左右区间是蓝色的$[l,r]$,那么上界会被限制在$w[i]$这条黄线处,能向上延伸的矩形数量也就是$a-w[i]$

由于$a$是定值,因此我们考虑每个$w[i]$会对多少个区间$[l,r]$产生贡献

显然,$w[i]$必须是区间$[l,r]$中的最大值!

因此扫到每一个$a$,答案就变成了$\frac{c(c+1)}{2}a-\sum_{i=1}^{c}\sum_{j=i}^{c}max(i,j)$,其中$max(i,j)$表示区间$[i,j]$中最大的$w$

这个看着可以用单调栈维护维护嘛...

可是我们每次向下扫描的时候,$w$都会改变!

因此我们需要一个能够支持修改的数据结构,显然是一种二叉树

这个二叉树需要支持修改,最好能保证是一个大根堆,而且还要保证中序遍历得到的是原序列

这个...有点难?

treap嘛!

把序列的下标扔进二叉搜索树里,再把$w$作为权值体现堆的性质就可以了嘛

(其实就是把原来随机的一个权值变成了一个$w$)

由于数据随机,所以可以通过

这样每个点的贡献就是$(siz[lson]+1)(siz[rson]+1)w$

注意在修改时如果先删除再重新插入会T,考虑到每次修改权值只增不减,因此每个节点只会向上转,因此我们直接修改即可

代码:

#include <cstdio>
#include <algorithm>
#define ll unsigned long long
#define ls tree[rt].lson
#define rs tree[rt].rson
using namespace std;
struct Treap
{
int lson,rson;
int size,val;
int rank;
ll sum;
}tree[];
struct POS
{
int x,y;
friend bool operator < (POS a,POS b)
{
return a.x<b.x;
}
}p[];
int tot=;
int rot;
ll sum=;
int r,c,n;
inline void update(const int &rt)
{
tree[rt].size=tree[ls].size+tree[rs].size+;
tree[rt].sum=1ll*(tree[ls].size+)*1ll*(tree[rs].size+)*tree[rt].rank+tree[ls].sum+tree[rs].sum;
}
inline void lturn(int &rt)
{
int temp=rs;
rs=tree[temp].lson;
tree[temp].lson=rt;
tree[temp].size=tree[rt].size;
update(rt);
rt=temp;
}
inline void rturn(int &rt)
{
int temp=ls;
ls=tree[temp].rson;
tree[temp].rson=rt;
tree[temp].size=tree[rt].size;
update(rt);
rt=temp;
}
void buildtree(int &rt,int l,int r)
{
rt=++tot;
if(l==r){tree[rt].val=l,tree[rt].size=;return;}
int mid=(l+r)>>;
tree[rt].val=mid;
if(l<mid)buildtree(ls,l,mid-);
if(r>mid)buildtree(rs,mid+,r);
update(rt);
}
void ins(int &rt,int v,int w)
{
if(!rt)return;
if(tree[rt].val==v)
{
tree[rt].rank=w;
update(rt);
return;
}
if(v<tree[rt].val)
{
ins(ls,v,w);
if(tree[ls].rank>tree[rt].rank)rturn(rt);
}else
{
ins(rs,v,w);
if(tree[rs].rank>tree[rt].rank)lturn(rt);
}
update(rt);
}
inline int read()
{
int f=,x=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int main()
{
r=read(),c=read(),n=read();
for(register int i=;i<=n;++i)p[i].x=read(),p[i].y=read();
buildtree(rot,,c);
ll ans=;
sort(p+,p+n+);
int las=;
for(register int i=;i<=r;++i)//枚举每一行
{
while(p[las].x==i&&las<=n)ins(rot,p[las].y,i),las++;
ans+=c*(c+)/*1ll*i-tree[rot].sum;
}
printf("%llu\n",c*(c+)/2ll*1ll*r*(r+)/2ll-ans);
return ;
}

bzoj 2658的更多相关文章

  1. BZOJ 2658 小蓝的好友

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2658 题意:给出一个n*m的格子.某些格子中有障碍.求包含至少一个障碍的矩形有多少 ...

  2. @bzoj - 2658@ [Zjoi2012]小蓝的好友(mrx)

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事 ...

  3. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  4. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  5. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  6. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  7. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

  8. 【sdoi2013】森林 BZOJ 3123

    Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...

  9. 【清华集训】楼房重建 BZOJ 2957

    Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...

随机推荐

  1. ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 27. CICD Azure DevOps

    VSTS做持续集成 后来改名叫做Azure Deveps https://azure.microsoft.com/zh-cn/services/devops/ 这是中文的地址 创建一个项目 名称.描述 ...

  2. python 并发编程之IO 模型

    首先说一下 IO 发生时涉及的对象和步骤.以read 为例,会经历两个阶段: 1)等待数据准备 2)将数据从内核拷贝到进程中 二,阻塞Io(blocking IO) 在 Linux中  默认情况下所有 ...

  3. 跟我学: 使用 fireasy 搭建 asp.net core 项目系列之三 —— 配置

    ==== 目录 ==== 跟我学: 使用 fireasy 搭建 asp.net core 项目系列之一 —— 开篇 跟我学: 使用 fireasy 搭建 asp.net core 项目系列之二 —— ...

  4. hdoj5289【RMQ+二分】【未完待续】

    思路: 对当前值查找最近满足位置: 利用RMQ求出区间最大最小值,再枚举右端点,二分区间找到满足要求的最大区间累加

  5. 51nod1352(exgcd)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1352 题意:中文题诶- 思路:exgcd 显然题目可以描述为: ...

  6. Codevs 1794 修剪花卉

    1794 修剪花卉   题目描述 Description ZZ对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题. 一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿 ...

  7. 第二篇 HTML5打包发布IOS APP之苹果开发者账号申请流程

    打包技术转移到了公众号

  8. Faster_Rcnn在windows下运行踩坑总结

    Faster_Rcnn在windows下运行踩坑总结  20190524 今天又是元气满满的一天! 1.代码下载 2.编译 3.下载数据集 4.下载pre-train Model 5.运行train ...

  9. Java的理解

    研发的工作就是写代码,我们通常写的都是java的类.这个东东计算机是无法识别的,所以需要需要一个东东帮我们做转化,这个就是编译器, 将java转换成class,但是class文件还不是二进制文件不是0 ...

  10. java数据结构----数组篇

    1.数组作为java常用的数据结构之一,使用相对简单,下图展示了数组常用操作在允许和不允许重复值的情况下的比较次数 2.进行封装后的代码: package com.cn.higharray; /** ...