bzoj 2658
首先考虑容斥
我们计算出所有没有点在其中的矩形,然后用所有矩形减去这些矩形即可
然后考虑如何计算没有点在其中的矩形
采用扫描线的思想,从上向下一行一行扫,假设我们扫到的行编号是$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的更多相关文章
- BZOJ 2658 小蓝的好友
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2658 题意:给出一个n*m的格子.某些格子中有障碍.求包含至少一个障碍的矩形有多少 ...
- @bzoj - 2658@ [Zjoi2012]小蓝的好友(mrx)
目录 @description@ @solution@ @accepted code@ @details@ @description@ 终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事 ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
- 【sdoi2013】森林 BZOJ 3123
Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...
- 【清华集训】楼房重建 BZOJ 2957
Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...
随机推荐
- 【Hadoop】MapReduce笔记(四):MapReduce优化策略总结
Cloudera 提供给客户的服务内容之一就是调整和优化MapReduce job执行性能.MapReduce和HDFS组成一个复杂的分布式系统,并且它们运行着各式各样用户的代码,这样导致没有一个快速 ...
- 极客时间_Vue开发实战_06.Vue组件的核心概念(2):事件
06.Vue组件的核心概念(2):事件 通过emit传递给父组件 我们点击了重置失败,上层的div的click=handleDivClick是接收不到.重置失败的点击的行为的 通常情况下,你不用.st ...
- Oracle中的集合运算
前言:在实际项目中对多表进行集合运算使用非常广泛,以下是对集合操作的部分总结. 一,建表,插入测试数据 create table a( numbers integer ) create table b ...
- TextBox禁用与启用的方法
$('#text1').textbox('enable');// 启用 $('#text1').textbox('disable');// 禁用 注:以上方法也适用于datebox等等
- 3DMAX 如何将删去的面补回来
1.例如下面长方体被删除一个面 2.点击主键盘区数字键[3] ,进入[边界]修改模式 ,使用鼠标点击 被删除面的边界,并点击[修改面板]---[封口],例如下图:
- CSproject文件总是在Solution中被修改PROJECT GUID问题
1.情况: 打开2个Solution 一个是client,一个是server 他们会互相修改GUID,切换solution的时候都会显示 xxxxx已经被外部修改云云 2.原因: 一般是在其中一个So ...
- 稳定UI运行结果-自动化测试失败重试和截图
运行自动化测试的时候,有时会因为网络不稳定,测试环境或者第三方环境正在重启而造成用例运行结果不稳定,时而能跑过时而跑不过.这些难以重现的环境因素造成的用例失败会让测试人员很困扰,排查即耗费时间也没有太 ...
- Linux安装Loadrunner generator
安装环境:redhat 6.5 64位版 从网上下载 loadrunner-11-load-generator.iso 文件 先创建一个iso 目录,用来挂载 iso 文件 mkdir iso 挂载i ...
- MyBatist庖丁解牛(五)
很多时候我们在自己的每个service中没有中注入SqlSessionTemplate; 但是我们直接调用mapper接口方法就直接能够操作数据库 这个是为什么??下面开始解惑: Mybatis Sq ...
- 关于log
如果项目上过线的话,那你一定知道Log是多么重要. 为什么说Log重要呢?因为上线项目不允许你调试,你只能通过Log来分析问题.这时打一手好Log的重要性绝不亚于写一手好代码.项目出问题时,你要能拿出 ...