首先考虑容斥

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

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

采用扫描线的思想,从上向下一行一行扫,假设我们扫到的行编号是$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. JQuery学习笔记(二)JQuery方法

    jQuery 提供一系列与 DOM 相关的方法,便于访问和操作元素和属性 Query 文档操作方法 这些方法对于 XML 文档和 HTML 文档均是适用的,除了:html(). 方法 描述 addCl ...

  2. 牛客 - 700I - Matrix Again - 二维RMQ - 二分

    https://ac.nowcoder.com/acm/contest/700/I 二维RMQ,贴个板子,注意爆内存,用char就可以了,char也可以存负数. 然后二分枚举对角线长度,理由很简单. ...

  3. PhpStorm插件之Api Debugger

    安装插件 File->Setting->Pluugins   搜索  Api Debugger 如何使用 安装完插件后,RESTART IDE,在编辑器右侧 即可找到最新安装的 Api D ...

  4. Codeforces Round #269 (Div. 2) A,B,C,D

    CodeForces - 471A 首先要有四个数相等,然后剩下两个数不同就是Bear,否则就是Elephant. #include <bits/stdc++.h> using names ...

  5. [HNOI2010] 物品调度 fsk

    标签:链表+数论知识. 题解: 对于这道题,其实就是两个问题的拼凑,我们分开来看. 首先要求xi与yi.这个可以发现,x每增加1,则pos增加d:y每增加1,则pos增加1.然后,我们把x与y分别写在 ...

  6. [Xcode 实际操作]一、博主领进门-(1)iOS项目的创建和项目模板的介绍

    目录:[Swift]Xcode实际操作 本文将演示iOS项目的创建和项目模板的介绍. [Create a new Xcode project]创建一个新的项目. 在弹出的模板窗口中,显示了所有的项目模 ...

  7. C语言提高代码效率的几种方法

    一段完美的代码不仅在于找到一个给定的问题的解决方案,但在它的简单性,有效性,紧凑性和效率(内存).设计的代码比实际执行更难.因此,每一个程序员当用C语言开发时,都应该保持这些基本的东西在头脑中.本文向 ...

  8. 黑马MySQL数据库学习day02 表数据CRUD 约束CRUD

    /* 基础查询练习: 1.字段列表查询 当查询全部字段时,一种简便方式,使用*代替全部字段(企业中不推荐使用) 2.去除重复行 DISTINCT,注意修饰的是行,也就是整个字段列表,而不是单个字段. ...

  9. JIRA中的标记语言的语法参考

    前言 看到网上有的文章说JIRA是使用Textile这门标记语言,有些语法和Wikitext和Markdown相像.JIRA在2017年进行了一次大更新,某些语法可能和以前不大一样,这里纪录一下常用的 ...

  10. SpringBoot | Velocity template

    SpringBoot版本: <parent> <groupId>org.springframework.boot</groupId> <artifactId& ...