题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2658

题意:给出一个n*m的格子。某些格子中有障碍。求包含至少一个障碍的矩形有多少个?

思路:我们求空白矩形的个数。

从上到下一行一行计算,每到达一行,计算以该行为底的空白矩形个数。我们只需要知道每列向上延伸的最大距离。

这个可以看做是一棵树

我们只需要记录每个的高度即可。

那么每次增加一行,若整行都没有障碍,则根节点的高度增加1.否则,障碍将树分为若干子树。这个操作可以用fhq treap实现,即通过树的分离和合并实现所有操作。

合并两个子树AB时,要求A的所有元素小于B。或者将A设为B的左孩子,或者将B设为A的右孩子。这个操作比较简单。

对于分离操作,用split(now,x,y,K)表示,将now为根的子树的前K个孩子分离,分开后的两个子树的根分别是x,y

设K=5

分离红色圈住的5个节点,过程如下:

(这个图来自http://hi.baidu.com/wdxertqdtscnwze/item/7b6a9419be7c68cd756a8498)

const int N=100005;

struct node
{
    int c[2],h,det,size;
    i64 ans;

    void add(int x)
    {
        h+=x;
        det+=x;
    }
};

node a[N];
int root;

#define C2(x) ((x)*((x)+1)/2)

void pushUp(int t)
{
    if(!t) return;
    a[t].size=1;
    a[t].ans=0;
    for(int i=0;i<2;i++) if(a[t].c[i])
    {
        int p=a[t].c[i];
        a[t].size+=a[p].size;
        a[t].ans+=a[p].ans;
        a[t].ans+=(i64)(a[p].h-a[t].h)*C2(a[p].size);
    }
}

void pushDown(int t)
{
    if(!t||!a[t].det) return;
    if(a[t].c[0]) a[a[t].c[0]].add(a[t].det);
    if(a[t].c[1]) a[a[t].c[1]].add(a[t].det);
    a[t].det=0;
}

pair<int,int> split(int u,int k)
{
    if(!u) return MP(0,0);
    pushDown(u);
    if(a[a[u].c[0]].size+1<=k)
    {
        k-=a[a[u].c[0]].size+1;
        pair<int,int> tmp=split(a[u].c[1],k);
        a[u].c[1]=tmp.first;
        pushUp(u);
        return MP(u,tmp.second);
    }
    else
    {
        pair<int,int> tmp=split(a[u].c[0],k);
        a[u].c[0]=tmp.second;
        pushUp(u);
        return MP(tmp.first,u);
    }
}

int merge(int u,int v)
{
    if(!u||!v) return u+v;
    pushDown(u);
    pushDown(v);
    if(a[u].h<a[v].h)
    {
        a[u].c[1]=merge(a[u].c[1],v);
        pushUp(u);
        return u;
    }
    else
    {
        a[v].c[0]=merge(u,a[v].c[0]);
        pushUp(v);
        return v;
    }
}

pair<int,int> b[N];
int n,m,K;

int main()
{

    n=myInt();
    m=myInt();
    K=myInt();
    for(int i=1;i<=K;i++)
    {
        b[i].first=myInt();
        b[i].second=myInt();
    }
    sort(b+1,b+K+1);
    for(int i=1;i<=m;i++)
    {
        root=merge(root,i);
        pushUp(root);
    }
    int cur=1;
    i64 ans=(i64)C2(n)*C2(m);

    for(int i=1;i<=n;i++)
    {
        a[root].add(1);
        while(cur<=K&&b[cur].first==i)
        {
            pair<int,int> tmp1=split(root,b[cur].second-1);
            pair<int,int> tmp2=split(tmp1.second,1);
            a[tmp2.first].h=0;
            root=merge(tmp1.first,tmp2.first);
            root=merge(root,tmp2.second);
            cur++;
        }
        ans-=a[root].ans;
        ans-=(i64)a[root].h*C2(a[root].size);
    }
    printf("%lld\n",ans);
}

BZOJ 2658 小蓝的好友的更多相关文章

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

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

  2. 【BZOJ2658】[Zjoi2012]小蓝的好友(mrx) 平衡树维护笛卡尔树+扫描线

    [BZOJ2658][Zjoi2012]小蓝的好友(mrx) Description 终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事,为了回馈各位比赛选手,此题的主角是贯穿这次比赛的 ...

  3. 洛谷 P2611 [ZJOI2012]小蓝的好友 解题报告

    P2611 [ZJOI2012]小蓝的好友 题目描述 终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事,为了回馈各位比赛选手,此题的主角是贯穿这次比赛的关键人物--小蓝的好友. 在帮小 ...

  4. 【BZOJ2658】[Zjoi2012]小蓝的好友(mrx) (扫描线,平衡树,模拟)

    题面 终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事,为了回馈各位比赛选手,此题的主角是贯穿这次比赛的关键人物--小蓝的好友. 在帮小蓝确定了旅游路线后,小蓝的好友也不会浪费这个难得 ...

  5. bzoj2658: [Zjoi2012]小蓝的好友(mrx)

    太神辣 treap的随机键值竟然能派上用场.. 要用不旋转的treap来进行维护区间信息 #include<cstdio> #include<cstring> #include ...

  6. BZOJ2658 ZJOI2012 小蓝的好友(treap)

    显然转化为求不包含关键点的矩形个数.考虑暴力,枚举矩形下边界,求出该行每个位置对应的最低障碍点高度,对其建笛卡尔树,答案即为Σhi*(slson+1)*(srson+1),即考虑跨过该位置的矩形个数. ...

  7. [ZJOI2012]小蓝的好友

    https://www.luogu.org/problemnew/show/P2611 题解 \(n\times m\)肯定过不去.. 我们把给定的点看做障碍点,考虑先补集转化为求全空矩阵. 然后我们 ...

  8. bzoj 2658

    首先考虑容斥 我们计算出所有没有点在其中的矩形,然后用所有矩形减去这些矩形即可 然后考虑如何计算没有点在其中的矩形 采用扫描线的思想,从上向下一行一行扫,假设我们扫到的行编号是$a$,然后考虑如果左右 ...

  9. P2611-[ZJOI2012]小蓝的好友【Treap,扫描线】

    正题 题目链接:https://www.luogu.com.cn/problem/P2611 题目大意 \(r*c\)的网格上有\(n\)个标记点,然后求有多少个矩形包含至少一个标记点. \(1\le ...

随机推荐

  1. oracle数据库的归档模式

    1:开发环境和测试环境中,数据库的日志模式和自动归档模式一般都是不设置的,这样有利于系统应用的调整,也免的生成大量的归档日志文件将磁盘空间大量的消耗. 2:生产环境时,将其设置为日志模式并自动归档就相 ...

  2. 夺命雷公狗---node.js---20之项目的构建在node+express+mongo的博客项目5mongodb在项目中实现添加数据

    我们上一步就引入了mongodb了,那么下一步就要开始写添加数据了,不过有个前提是先将表单的数据处理好: 最基本的这部现在已经成功了,因为最基本的这步就是先将表单处的提交方式和提交地址给处理好,这里和 ...

  3. DDR(一)

    P-Bank:计算机早期的一个概念.目的:匹配内存芯片和CPU芯片的数据总线的宽度.方法:并联多个内存模块. L-Bank:对内部存储阵列的分割,避免寻址冲突,提高内存效率.通过ba信号选择bank, ...

  4. 9. 星际争霸之php设计模式--代理模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  5. [Ubuntu] Linux下使用google app engine,无法打开https网站的解决方法

    为什么这里写的是 google app engine?原因我就不解释了.步骤如下: 1)安装证书导入工具:$ sudo apt-get install libnss3-tools 2)导入CA.crt ...

  6. NOIP200407合唱队形+最长上升子序列O(n^2)详解

    合唱队形解题报告 2016-05-12   4:30——6:45 NOIP200407合唱队形 难度级别:A: 运行时间限制:1000ms: 运行空间限制:256000KB: 代码长度限制:20000 ...

  7. Openstack的HA解决方案【mysql集群配置】

    使用mysql的galera做多主集群配置,galera的集群优势网络上面有对比,这里不在叙述. 1. 新建3台虚拟机(centos6.5) node1:172.17.44.163 node2:172 ...

  8. centos安装apache

    查询是否已安装apache:  rpm -qa httpd 安装apache: yum install httpd -y 查询: chkconfig httpd on 启动: service http ...

  9. java继承关系中成员变量,构造方法,成员方法的关系

    Java继承中的成员关系 A:成员变量 a:子类的成员变量名称和父类中的成员变量名称不一样,这个太简单写那个名字就访问那个名字! b:子类的成员变量名称和父类中的成员变量名称一样,这个怎么访问呢? 子 ...

  10. ServiceStack.Redis 使用教程

    http://www.cnblogs.com/shanyou/archive/2011/11/10/2245082.html https://github.com/ServiceStack/Servi ...