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栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...
随机推荐
- 11.ClientCredential模式总结
11.ClientCredential模式总结 服务端定义的Resource叫做api Resource API默认是被保护的 第三方的客户端先去请求 Server拿到access token.带着t ...
- visualstudio Team Foundation Server 使用教程
一.前沿 Team Foundation Server 是我们开发者使用最多的源代码管理工具.由于自己服务器搭建拉取工作慢的缘故,我使用了微软的 TFS.使用非常方便.快捷.免费.且不公开私有的项目. ...
- 洛谷 - P1020 - 导弹拦截 - 最长上升子序列
https://www.luogu.org/problemnew/show/P1020 终于搞明白了.根据某定理,最少需要的防御系统的数量就是最长上升子序列的数量. 呵呵手写二分果然功能很多,想清楚自 ...
- layui常用功能
包含的主要样式: 验证不通过时的弹窗 弹窗修改信息 询问框(是否删除之类的) 操作成功提示.操作失败提示 加载样式(显示加载层) 文件下载请前往github over!over!over!
- node中的url模块解析结果
1. URL模块作用: url 模块用于处理与解析 URL. 使用方法如下: const url = require('url'); 2. URL 字符串与 URL 对象 URL 字符串是结构化的字符 ...
- MFC的CString使用
CString没有基类.一个CString对象由可变长度的一队字符组成.CString使用类似于Basic的语法提供函数和操作符.连接和比较操作符以及简化的内存管理使CString对象比普通字符串数组 ...
- 洛谷P4884 多少个1?(BSGS)
传送门 模数好大……__int128好麻烦……而且BSGS第一次写有点写蒙了…… $11...1(N个1)\equiv k(mod m)$很难算,那么考虑转化一下 先把$11...1(N个1)$写成$ ...
- [Xcode 实际操作]九、实用进阶-(8)实现App的Setting设置:添加和读取程序的配置信息
目录:[Swift]Xcode实际操作 本文将演示如何实现添加和读取程序的配置信息. 在项目文件夹[DemoApp]上点击鼠标右键->[New File]创建一个设置束文件 ->[Sett ...
- “我要点爆”微信小程序云开发实例
使用云开发进行微信小程序“我要点爆”的制作 下一章:“我要点爆”微信小程序云开发之项目建立与我的页面功能实现 接下来我将对“我要点爆”微信小程序进行完整的开源介绍 小程序名称: 我要点爆 查看方式:从 ...
- Spring事件机制详解
一.前言 说来惭愧,对应Spring事件机制之前只知道实现 ApplicationListener 接口,就可以基于Spring自带的事件做一些事情(如ContextRefreshedEvent),但 ...