https://www.luogu.org/problemnew/show/P2611

题解

\(n\times m\)肯定过不去。。

我们把给定的点看做障碍点,考虑先补集转化为求全空矩阵。

然后我们枚举每一行,令这一行每个点的权值为从这点向上的极大不包含障碍点的连续段。

然后对这个序列建立笛卡尔树,那么答案为:

\[f[x]=(h[x]-h[fa[x]])*\frac{szie[x]*(size[x]+1)}{2}
\]

我们的笛卡尔树上的的每个节点都要维护一个这样的信息。

现在我们还需要扫描每一行,动态维护这颗笛卡尔树。

如果这行没有障碍点,我们整体加个1就好了,这个可以直接打标记。

对于障碍点,相当于这个位置的值变成了0,那么我们把这个点旋转上来就好了,通过手玩我们可以发现\(rotate\)操作不会破坏除了这个点以外的其他点的笛卡尔树结构,于是我们可以一直\(rotate\)把这个点转上去,顺便更新一下答案就好了,因为是随机的数据,所以每次期望操作次数是\(log\)的。

注意如果按照上面的\(\Delta h\)那样算贡献的话如果一个点的父亲改变了的话这个点需要重新\(pushup\)一次。

代码

  1. #include<bits/stdc++.h>
  2. #define N 100009
  3. #define ls tr[x][0]
  4. #define rs tr[x][1]
  5. using namespace std;
  6. typedef long long ll;
  7. vector<int>vec[N];
  8. vector<int>::iterator it;
  9. int tr[N][2],fa[N],size[N],h[N],la[N],n,m,num,rot;
  10. ll dp[N],ans;
  11. inline ll rd(){
  12. ll x=0;char c=getchar();bool f=0;
  13. while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
  14. while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
  15. return f?-x:x;
  16. }
  17. inline ll calc(ll x){return x*(x+1)/2;}
  18. inline bool ge(int x){return tr[fa[x]][1]==x;}
  19. inline void pushup(int x){
  20. size[x]=size[ls]+size[rs]+1;
  21. dp[x]=dp[ls]+dp[rs]+1ll*(h[x]-h[fa[x]])*calc(size[x]);
  22. }
  23. inline void rotate(int x){
  24. int y=fa[x],o=ge(x);
  25. tr[y][o]=tr[x][o^1];fa[tr[y][o]]=y;
  26. if(fa[y])tr[fa[y]][ge(y)]=x;fa[x]=fa[y];
  27. fa[y]=x;tr[x][o^1]=y;
  28. if(tr[y][o])pushup(tr[y][o]);pushup(y);pushup(x);
  29. }
  30. inline void add(int x,int y){
  31. h[x]+=y;la[x]+=y;
  32. pushup(x);
  33. }
  34. inline void pushdown(int x){
  35. if(la[x]){
  36. if(ls)add(ls,la[x]);
  37. if(rs)add(rs,la[x]);
  38. la[x]=0;
  39. }
  40. }
  41. void _pushdown(int x){
  42. if(fa[x])_pushdown(fa[x]);
  43. pushdown(x);
  44. }
  45. int build(int l,int r){
  46. if(l>r)return 0;
  47. int x=(l+r)>>1;
  48. ls=build(l,x-1);rs=build(x+1,r);
  49. if(ls)fa[ls]=x;if(rs)fa[rs]=x;
  50. size[x]=size[ls]+size[rs]+1;
  51. return x;
  52. }
  53. void dfs(int x){
  54. pushdown(x);
  55. if(ls)dfs(ls);
  56. cout<<x<<" "<<ls<<" "<<rs<<" "<<h[ls]<<" "<<h[rs]<<" "<<h[x]<<" "<<dp[x]<<endl;
  57. if(rs)dfs(rs);
  58. }
  59. int main(){
  60. n=rd();m=rd();num=rd();
  61. rot=build(1,m);
  62. for(int i=1;i<=num;++i){
  63. int x,y;
  64. x=rd(),y=rd();
  65. vec[x].push_back(y);
  66. }
  67. for(int i=1;i<=n;++i){
  68. add(rot,1);
  69. for(it=vec[i].begin();it!=vec[i].end();++it){
  70. int x=*it;
  71. _pushdown(x);
  72. while(fa[x])rotate(x);
  73. h[x]=0;
  74. if(ls)pushup(ls);if(rs)pushup(rs);
  75. pushup(x);
  76. rot=x;
  77. }
  78. ans+=dp[rot];
  79. }
  80. printf("%lld",calc(n)*calc(m)-ans);
  81. return 0;
  82. }

[ZJOI2012]小蓝的好友的更多相关文章

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

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

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

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

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

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

  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. BZOJ 2658 小蓝的好友

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2658 题意:给出一个n*m的格子.某些格子中有障碍.求包含至少一个障碍的矩形有多少 ...

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

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

  9. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

随机推荐

  1. Centos 添加swap

    swap是linux系统的虚拟内存,物理内存不足时,会用到.生产环境,最好添加上,以防内存异常暴增时,系统出现问题. 查看系统是否有swap分区,执行如下命令,若Swap那一行都为0,则表示没有Swa ...

  2. 牛客网Java刷题知识点之数组、链表、哈希表、 红黑二叉树

    不多说,直接上干货! 首先来说一个非常形象的例子,来说明下数组和链表. 上体育课的时候,老师说:你们站一队,每个人记住自己是第几个,我喊到几,那个人就举手,这就是数组. 老师说,你们每个人记住自己前面 ...

  3. java中的各种修饰符作用范围

    访问修饰符: private 缺省 protected public 作用范围: 访问修饰符\作用范围 所在类 同一包内其他类 其他包内子类 其他包内非子类 private 可以访问 不可以 不可以 ...

  4. C#的split()分割字符串

    简单的说: 在C#中 str.Split("===="); //这样是错误的,只能 str.Split('=');//参数只能是char类型的,不能是字符串的 如果非得要以字符串分 ...

  5. java里面的package/import 和PHP里面的namespace/use 是一模一样的吗

    java里面的package/import 和PHP里面的namespace/use 是一模一样的吗? java: php package mypage; namespace mypage; impo ...

  6. Linux kernel workqueue机制分析

    Linux kernel workqueue机制分析 在内核编程中,workqueue机制是最常用的异步处理方式.本文主要基于linux kernel 3.10.108的workqueue文档分析其基 ...

  7. 搭建Vue2.0开发环境

    1.必须要安装nodejs 2.搭建vue的开发环境 ,安装vue的脚手架工具 官方命令行工具 npm install --global vue-cli / cnpm install --global ...

  8. 2017年10月9日 冒泡&去重复习

    今天看了一下,就是数组跟js还是不太熟悉 冒泡排序    var arr = [4, 2, 1, 3, 6, 5];        for(var i = 1; i < arr.length; ...

  9. 动态网页开发jsp

    1.动态网页的优势?    ①交互性:即网页会根据用户的要求和选择而动态改变和显示内容.    ③自动更新:即无需改变页面代码,便会自动生成新的页面内容.    ④随机性:即当不同的时间.不同的人访问 ...

  10. scss-!default默认变量

    在变量赋值之前, 利用!default为变量指定默认值. 也就是说,如果在此之前变量已经赋值,那就不使用默认值,如果没有赋值,则使用默认值. 代码实例如下: $content: "antzo ...