首先考虑容斥

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

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

采用扫描线的思想,从上向下一行一行扫,假设我们扫到的行编号是$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. 【Hadoop】MapReduce笔记(四):MapReduce优化策略总结

    Cloudera 提供给客户的服务内容之一就是调整和优化MapReduce job执行性能.MapReduce和HDFS组成一个复杂的分布式系统,并且它们运行着各式各样用户的代码,这样导致没有一个快速 ...

  2. TypeScript完全解读(26课时)_8.ES6精讲-ES6中的类(进阶)

    8.TypeScript完全解读-ES6精讲-类(进阶) 在index.ts内引入 Food创建的实例赋值给Vegetabled这个原型对象,这样使用Vegetables创建实例的时候,就能继承到Fo ...

  3. python-re使用举例

    代码: import re text = "JGood is a handsome boy, he is cool, clever, and so on..." print(tex ...

  4. 一张图入门git系列

    github地址:https://github.com/521xueweihan/git-tips

  5. js微信摇一摇功能以及api

    一.摇一摇功能 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  6. CentOS 6.5 升级gcc到4.8 以及libstdc++

    CentOS 6.5 自带gcc太旧不支持c11, 升级到4.8的步骤: 引用: http://cache.baiducontent.com/c?m=9d78d513d99216f31eb0d5690 ...

  7. 原生js回到顶部

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  8. Android NFC 整理

    Android NFC基础(多篇) http://blog.csdn.net/think_soft/article/details/8169483

  9. Mysql | 总结 | 常用的查询语句(单表查询)

    1. 查询单表全部 select* from 数据表名; 2. 查询单表中一个或者多个字段 select 字段1,字段2 from 数据表名; 3. 查询单表中的指定信息 select* from 数 ...

  10. 洛谷2758(字符串dp)

    题目传送 记得这是我初学dp时的一道题 虽说就像LCS一样搞一搞即可 但我还是写挂了qwq #include <cstdio> #include <cstring> #incl ...