扫描线+区间更新

题解

  1. /*
  2. st[i],ol[i]表示y坐标大于y[i]和小于y[i]的点
  3. 两颗线段树建立在y轴上,区间[l,r]ol线选在[l,r]时st的分数
  4. 每次查询完成后再更新一次
  5. 遍历每条st线上的ol线,这是单点查询
  6. */
  7. #include<iostream>
  8. #include<cstring>
  9. #include<cstdio>
  10. #include<map>
  11. #include<vector>
  12. #include<algorithm>
  13. using namespace std;
  14. #define N 200005
  15. #define LL(x) (x<<1)
  16. #define RR(x) (x<<1|1)
  17. #define MID(a,b) (a+((b-a)>>1))
  18.  
  19. struct Point{
  20. int x,y;
  21. void get(){scanf("%d%d",&x,&y);}
  22. bool operator<(const Point & b)const
  23. { return x<b.x; }
  24. } p[N];
  25. struct node{//线段树结点
  26. int lft,rht;
  27. int flag[];
  28. int mid(){return MID(lft,rht);}
  29. void init(int a,int b){flag[]=a;flag[]=b;}
  30. };
  31. int n,m,mi;
  32. vector<int> mx;
  33. map<int,int> H;
  34. int y[N],st[N],ol[N];//离散化数轴,大于等于y[i]的点数,小于等于y[i]的点
  35. struct Segtree{
  36. node tree[N*];
  37. void down(int ind){
  38. for(int i=;i<;i++){
  39. tree[LL(ind)].flag[i]+=tree[ind].flag[i];
  40. tree[RR(ind)].flag[i]+=tree[ind].flag[i];
  41. tree[ind].flag[i]=;
  42. }
  43. }
  44. void build(int lft,int rht,int ind){
  45. tree[ind].lft=lft;tree[ind].rht=rht;
  46. tree[ind].init(,);
  47. if(lft==rht) tree[ind].init(st[lft],ol[lft]);
  48. else {
  49. int mid=tree[ind].mid();
  50. build(lft,mid,LL(ind));
  51. build(mid+,rht,RR(ind));
  52. }
  53. }
  54. void update(int st,int ed,int ind,int type,int valu){
  55. int lft=tree[ind].lft,rht=tree[ind].rht;
  56. if(st<=lft && ed>=rht)
  57. tree[ind].flag[type]+=valu;
  58. else {
  59. down(ind);
  60. int mid=tree[ind].mid();
  61. if(st<=mid) update(st,ed,LL(ind),type,valu);
  62. if(ed>mid) update(st,ed,LL(ind),type,valu);
  63. }
  64. }
  65. void query(int pos,int ind,int &mi,int &mx){
  66. if(tree[ind].lft==tree[ind].rht){
  67. mi=tree[ind].flag[];
  68. mx=tree[ind].flag[];
  69. }
  70. else {
  71. down(ind);
  72. int mid=tree[ind].mid();
  73. if(pos<=mid) return query(pos,LL(ind),mi,mx);
  74. if(pos>mid) return query(pos,RR(ind),mi,mx);
  75. }
  76. }
  77. }seg;
  78. int main(){
  79. while(scanf("%d",&n),n){
  80. H.clear();mx.clear();mi=m=;
  81.  
  82. int id1=,id2=;
  83. for(int i=;i<n;i++){
  84. p[i].get();
  85. y[i]=p[i].y;
  86. }
  87. sort(y,y+n);
  88. sort(p,p+n);//把点按从左往右顺序排好
  89. H[y[]]=;
  90. for(int i=;i<n;i++)//遍历一次纵坐标
  91. if(y[m]!=y[i]){
  92. st[m]=n-i;//高于y[i]的点数
  93. y[++m]=y[i];
  94. ol[m]=i;//低于y[i]的点数
  95. H[y[m]]=m;
  96. }
  97. st[m]=;
  98. seg.build(,m,);
  99. while(id1<n){
  100. id2=id1;
  101. while(p[id1].x==p[id2].x){//这一步删掉被st线穿过的点
  102. //不是最低的点
  103. if(p[id2].y!=y[]) //ol线低于p[id2].y情况的st分数就少了一份
  104. seg.update(H[y[]],H[p[id2].y]-,,,-);
  105. //不是最高的点
  106. if(p[id2].y!=y[m]) //ol线高于p[id2].y的时候
  107. seg.update(H[p[id2].y]+,H[y[m]],,,-);
  108. if(++id2>=n) break;
  109. }
  110. int mii=n,mxx=;
  111. for(int i=id1;i<id2;i++){//依次在st线上的点建立ol线并进行查询,找到使st得分最低的那个点
  112. int tmp1,tmp2;
  113. seg.query(H[p[i].y],,mii,mxx);
  114. mii=min(mii,tmp1);
  115. mxx=max(mxx,tmp2);
  116. }
  117.  
  118. if(mii==mi) mx.push_back(mxx);//找到了ol的新解
  119. else if(mii>mi){//找到了st的更优解
  120. mi=mii;
  121. mx.clear();mx.push_back(mxx);
  122. }
  123. //再更新一次,把这条线上删掉的反向加回去:因为扫描线往后扫描这条线上原来应该属于ol的现在属于st,原来属于st的现在应该属于ol
  124. for(int i=id1;i<id2;i++){
  125. if(p[i].y!=y[])
  126. seg.update(H[y[]],H[p[i].y]-,,,);
  127. if(p[i].y!=y[m])
  128. seg.update(H[p[i].y]+,H[y[m]],,,);
  129. }
  130. id1=id2;
  131. }
  132. sort(mx.begin(),mx.end());
  133. mx.erase(unique(mx.begin(),mx.end()),mx.end());
  134. printf("Stan: %d; Ollie:",mi);
  135. for(int i=;i<mx.size();i++)
  136. printf(" %d",mx[i]);
  137. printf(";\n");
  138. }
  139. return ;
  140. }

poj2464扫描线好题,回头再做的更多相关文章

  1. cf276E 两棵线段树分别维护dfs序和bfs序,好题回头再做

    搞了一晚上,错了,以后回头再来看 /* 对于每次更新,先处理其儿子方向,再处理其父亲方向 处理父亲方向时无法达到根,那么直接更新 如果能达到根,那么到兄弟链中去更新,使用bfs序 最后,查询结点v的结 ...

  2. poj2464扫描线好题,树状数组解法

    用树状数组解比线段树快了好多,难度也下降许多 分别用两个树状数组维护当前扫描线左侧和右侧的点,离散化y轴即可 #include<iostream> #include<cstring& ...

  3. uva12436 回头再做一次

    线段树维护等差数列,结点维护首项+公差即可 #include <cstdio> #include <cstring> #include <algorithm> us ...

  4. hdu4942线段树模拟rotate操作+中序遍历 回头再做

    很有意思的题目,详细题解看这里 https://blog.csdn.net/qian99/article/details/38536559 自己的代码不知道哪里出了点问题 /* rotate操作不会改 ...

  5. Go: LeetCode简单题,简单做(sort.Search)

    前言 正值端午佳节,LeetCode也很懂.这两天都是简单题,早点做完去包粽子. 故事从一道简单题说起 第一个错误的版本 简单题 你是产品经理,目前正在带领一个团队开发新的产品.不幸的是,你的产品的最 ...

  6. CozyRSS开发记录3-标题栏再加强

    CozyRSS开发记录3-标题栏再加强 1.更精炼的标题栏 接下来,我们把窗口的边框和默认的标题栏给去掉,让Cozy看起来更像一个平板应用. 在主窗口的属性里,修改下列两个属性: 效果一目了然: 2. ...

  7. el-popover 的显示或隐藏,要在拿到真实dom之后再做控制

    el-popover 的显示或隐藏,要在拿到真实dom之后再做控制

  8. 【java】【多线程】等待开启的多个线程都执行完成,再做事情,怎么实现

    今天在controller中写一个接口用来测试模拟多个请求同时到达 下订单的情况, 怎么能有效保证高并发下的库存和销量的一致性呢?[具体实现方法:https://www.cnblogs.com/sxd ...

  9. Spark在处理数据的时候,会将数据都加载到内存再做处理吗?

    对于Spark的初学者,往往会有一个疑问:Spark(如SparkRDD.SparkSQL)在处理数据的时候,会将数据都加载到内存再做处理吗? 很显然,答案是否定的! 对该问题产生疑问的根源还是对Sp ...

随机推荐

  1. spring @Transactional注解参数详解

    事物注解方式: @Transactional 当标于类前时, 标示类中所有方法都进行事物处理 , 例子: @Transactional public class TestServiceBean imp ...

  2. 化工pdf下载

    Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...

  3. GBDT用于分类问题

    一.简介 GBDT在传统机器学习算法里面是对真实分布拟合的最好的几种算法之一,在前几年深度学习还没有大行其道之前,gbdt在各种竞赛是大放异彩.原因大概有几个 一:效果确实挺不错. 二:既可以用于分类 ...

  4. mysql优化问题汇总

    sql优化-->分区-->分表-->垂直分库-->水平分库-->读写分离 分区 关于分区的博客推荐这个:https://blog.csdn.net/youzhouliu/ ...

  5. <!--more-->搭建的博客设置主页内容高度

    用 markdown写文章时插入<!--more-->,文章会自动从插入的位置截断,也就是说在博客中只显示<!--more-->之前的内容,点击阅读全文之后会显示所有内容.

  6. Linux记录-TCP状态以及(TIME_WAIT/CLOSE_WAIT)分析(转载)

    1.TCP握手定理 2.TCP状态 l  CLOSED:初始状态,表示TCP连接是“关闭着的”或“未打开的”. l  LISTEN :表示服务器端的某个SOCKET处于监听状态,可以接受客户端的连接. ...

  7. cetus系列~安装和基本配置

    cetus系列一 安装   1 安装软件环境   yum install cmake gcc glib2-devel flex mysql-devel gperftools-libs  bison f ...

  8. UML和模式应用4:初始阶段(5)--用例编写的准则

    1.前言 本文主要介绍用例编写时所遵循的几条基本准则. 2.用例编写的准则 2.1 以本质的风格编写用例 如系统认证,而不要说 需要输入ID进行认证等 2.2 编写简洁的用例 如系统认证,不要说 这个 ...

  9. xpath与nodejs解析xml

    测试xpath的工具 http://www.freeformatter.com/xpath-tester.html#ad-output http://www.xpathtester.com/test ...

  10. #ifndef详解

    #ifndef 是"if not defined"的简写,是预处理功能(宏定义.文件包含.条件编译)当中的条件编译,可以根据是否已经定义了一个变量来进行分支选择,其作用是: 1.防 ...