传送门
思路:
神题
总结——写了一个错误做法,然后A了

想+写+调搞了将近一个星期
一开始想的是把斜着的线段转化成竖着的线段和横着的线段,然后分别做
但是好不容易打完以后,发现轻易就有反例(?)
然后先把题弃了,做了些简单题
学了圆的扫描线回来,发现这个题是可以用到的类似的思路,因为都是不相交的图形,可以通过交点的横纵坐标扔进set里搞一搞。
每添加进一个线段,就由它向它的前驱连边,由后继向它连边
每删除一个线段,就由它的后继向前驱连边
边数是O(n)O(n)的
由于上下移动,左右移动正好是相反的,所以分别拿x,y为关键字扫两次就能建出4个拓扑图来了
关于第二问,显然只往一个方向移动肯定是有解的,而且这些线段的关系是一个DAG
然后就建了四个方向的DAG……
处理线段端点相交的话,坐标相等时再按照左右端点为关键字选就可以了
过了样例后交了上去,结果

最上边的两次是暴力向前驱后继连边,边数为O(n2)O(n^2)
要来数据调,发现第2,3个点的第一问都过不了

那怎么跑的900ms+?
然后发现set出现了玄学的问题
yveh,ISA,DaD3zZ都过来看错误
最后yveh指出我的cmp函数竟然可以满足a<ba,b>ab>a同时成立
同时我搞了个dcmp,再测试就过了

用数据测了下,第1问是没问题了,但是第二问应该依然是错误的
可是仔细思考一下,我发现我的做法是对于每个合法操作,在各个拓扑图里暴力删线段,这样会使在某一次操作中,可能图中还有限制当前移动操作的线段,但由于不是预处理时的前驱,就在图中没有连边,导致本来非法的操作被判断为合法
这个bug影响第一问,但应该是不会影响第二问的,因为我们只要按照拓扑排序的顺序进行输出,得到的操作一定是合法的
发现自己自作聪明,把第一问中合法的操作存起来当做第二问的答案,然后闷声改了过来
但并没有修改上述bug
结果

这个结果不奇怪,因为我把数据下下来了,发现自己第一问没错
这更让人感到奇怪,出题人连这个bug都没卡吗?
顺手打开连带数据一起发的std
发现std中有这样一行

然后std和我写的做法是一样的
所以这个神题就被我这么水过去了= =

还没完……
去问TA爷,TA给出了一个解决办法:如果要删的线段在图中有出度,就打个标记;如果没有出度,就删掉它,并且找指向它的线段,出度-1,然后再如上判断,递归做下去
由于脑抽+对TA爷的仰慕,开始着手搞这个东西
但调了好久才意识到,这个做法也有bug
因为x前驱的前驱,不一定是x的前驱!
也就是std中那句”拓扑不具有传递性“的那句话!
”我终于又想出了一个错误做法“ ——by TA
所以自己思考是很重要的,不要盲信他人,即使是TA

正确的题解:传送门
错误的代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
#include<queue>
#include<cmath>
#include<cstdlib>
#define M 100005
using namespace std;
char *cp=(char *)malloc(20000000);
int n,seg,tot[4],cnt;
int A[M],B[M],C[M],D[M],first[4][M],deg[4][M],IN[M];
double KK[M],BB[M];
struct Point{int data,tp,id;
}a[M<<1];
struct edge{int v,next;
}e[4][M*3];
void add(int tp,int x,int y)
{e[tp][++tot[tp]]=(edge){y,first[tp][x]};first[tp][x]=tot[tp];++deg[tp][y];
}
double dis1(int id){return (seg-BB[id])/KK[id];}//求x
double dis2(int id){return KK[id]*seg+BB[id];}//求y
bool cmp(Point a,Point b)
{if (a.data==b.data) return a.tp>b.tp;return a.data<b.data;
}
bool fcmp(double a,double b)
{if (fabs(a-b)<=1e-7) return 0;return a>b;
}
struct node{int tp,id;//tp=0->扫描线上下移动,tp=1->扫描线左右移动 bool operator <(const node other)const{if (!tp)return fcmp(dis1(id),dis1(other.id));elsereturn fcmp(dis2(id),dis2(other.id));}
};
set<node> s;
set<node>::iterator it1,it2;
queue<int>q;
inline int in () { int x=0,f=0;for (;*cp<'0'||*cp>'9';cp++) f|=((*cp)=='-'); for (x=0;*cp>='0'&&*cp<='9';cp++)x=x*10+*cp-48; return f?-x:x;
}
void work1()//点按照y排序,扫描线上下移动,set中按照交点的x排序
{for (int i=1;i<=n;++i){a[i*2-1].data=B[i],a[i*2-1].tp=(B[i]>=D[i]);a[i*2].data=D[i],a[i*2].tp=(B[i]<D[i]);a[i*2-1].id=a[i*2].id=i;}sort(a+1,a+n*2+1,cmp);for (int i=1;i<=n<<1;++i){seg=a[i].data;node tmp=(node){0,a[i].id},t1,t2; if (a[i].tp){it1=s.lower_bound(tmp);it2=s.upper_bound(tmp);if (it1!=s.begin()&&it2!=s.end())t1=*(--it1),t2=*it2,add(2,t1.id,t2.id),add(0,t2.id,t1.id);s.erase(tmp);}else{it1=s.lower_bound(tmp);it2=s.upper_bound(tmp);if (it2!=s.end())t2=*it2,add(2,a[i].id,t2.id),add(0,t2.id,a[i].id);if (it1!=s.begin())t1=*(--it1),add(2,t1.id,a[i].id),add(0,a[i].id,t1.id);s.insert(tmp);}}
}
void work2()//点按照x排序,扫描线左右移动,set中按照交点的y排序
{for (int i=1;i<=n;++i)a[i*2-1].data=A[i],a[i*2-1].tp=(A[i]>=C[i]),a[i*2].data=C[i],a[i*2].tp=(A[i]<C[i]),a[i*2-1].id=a[i*2].id=i;sort(a+1,a+n*2+1,cmp);s.clear();for (int i=1;i<=n<<1;++i){seg=a[i].data;node tmp=(node){1,a[i].id},t1,t2; if (a[i].tp){it1=s.lower_bound(tmp);it2=s.upper_bound(tmp);if (it1!=s.begin()&&it2!=s.end())t1=*(--it1),t2=*it2,add(1,t1.id,t2.id),add(3,t2.id,t1.id);s.erase(tmp);}else{it1=s.lower_bound(tmp);it2=s.upper_bound(tmp);if (it2!=s.end())t2=*it2,add(1,a[i].id,t2.id),add(3,t2.id,a[i].id);if (it1!=s.begin())t1=*(--it1),add(1,t1.id,a[i].id),add(3,a[i].id,t1.id);s.insert(tmp);}}
}
main()
{fread(cp,1,20000000,stdin);n=in();for (int i=1;i<=n;++i)A[i]=in(),B[i]=in(),C[i]=in(),D[i]=in(),KK[i]=1.0*(B[i]-D[i])/(A[i]-C[i]),BB[i]=B[i]-KK[i]*A[i];work1();work2();for (int i=1;i<=n;++i) IN[i]=deg[0][i];for (int p,q,i=1;i<=n;++i){p=in();q=in();if (deg[q][p]){printf("%d\n",i);break;}for (int tp=0;tp<4;++tp)for (int j=first[tp][p];j;j=e[tp][j].next)--deg[tp][e[tp][j].v];}for (int i=1;i<=n;++i)if (!IN[i])q.push(i);for (;!q.empty();q.pop()){int k=q.front();printf("%d %d\n",k,0);for (int i=first[0][k];i;i=e[0][i].next){--IN[e[0][i].v];if (!IN[e[0][i].v])q.push(e[0][i].v);}}
}

【BZOJ2584】memory,扫描线+拓扑图+骗相关推荐

  1. BZOJ2584 : [Wc2012]memory

    xy方向分开考虑 用扫描线处理出拓扑序,第二问直接回答拓扑序, 第一问: 将操作倒过来,变成加入线段,用线段树维护区间拓扑序的最值 #include<cstdio> #include< ...

  2. 【POJ 2482】 Stars in Your Window(线段树+离散化+扫描线)

    [POJ 2482] Stars in Your Window(线段树+离散化+扫描线) Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

  3. What every programmer should know about memory 笔记

    What every programmer should know about memory, Part 1(笔记) 每个程序员都应该了解的内存知识[第一部分] 2.商用硬件现状 现在硬件的组成对于p ...

  4. 2021牛客多校6 - Hopping Rabbit(矩形取模+扫描线)

    题目链接:点击查看 题目大意:二维平面给出 nnn 个矩形,现在要求找到一个点 (x+0.5,y+0.5)(x+0.5,y+0.5)(x+0.5,y+0.5),满足对于任意的 (x+0.5+k1d,y ...

  5. 2021牛客暑期多校训练营6 Hopping Rabbit 扫描线 + 矩形 + 细节

    传送门 文章目录 题意: 思路: 题意: 给你nnn个矩形,以及一个距离ddd,让你找一个点(x+0.5,y+0.5)(x+0.5,y+0.5)(x+0.5,y+0.5),这个点一次能向四个方向跳dd ...

  6. 扫描线三巨头 hdu1928hdu 1255 hdu 1542 [POJ 1151]

    学习链接:http://blog.csdn.net/lwt36/article/details/48908031 学习扫描线主要学习的是一种扫描的思想,后期可以求解很多问题. 扫描线求矩形周长并 hd ...

  7. hdu 1255 覆盖的面积 (扫描线求矩形交)

    覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  8. 【BZOJ2758】Blinker的噩梦,扫描线+splay+链剖

    传送门 思路: 代码题 如果你已经做过一些扫描线的题目的话,这道题的思路一点都不难想: 不相交的图形→确定它们构成一棵树 如何确定这棵树→扫描线+set set中的比较函数→圆直接代入方程计算,凸多边 ...

  9. 基于HTML5的网络拓扑图 - 设备状态面板

    为什么80%的码农都做不了架构师?>>>    电信网管系统中,设备状态信息的实时展示非常重要,通常会挂载一堆图标来展示状态或告警信息,图标的信息量有限,有时需要更详细的面板,甚至以 ...

最新文章

  1. 重新编译iptables
  2. Xcode终端快捷键
  3. webform(八)——LinQ简单增、删、改、查
  4. 2011年计算机一级考试题,2011年计算机一级考试试题及答案
  5. 终于下决心写一写自己的博客了!
  6. chrome 浏览器之下载管理器插件
  7. leetcode--single number.
  8. python进阶06并发之二技术点关键词
  9. C#的String.Split方法
  10. 设计模式(9)——模板方法模式
  11. (二)零基础入门C语言 --- C语言之入门课程
  12. 基于matlab的简单人脸识别程序代码
  13. H5C3第二个完整大项目————天猫国际首页跳转登录页
  14. 通俗易懂的傅立叶级数理解
  15. 敏捷项目管理传统项目管理的区别
  16. 一文让你理解什么是shallow heap及retained heap
  17. 如何在Mac电脑中卸载软件?Mac电脑卸载软件方法汇总
  18. 利用Landsat8数据的不同波段组合监测冰雪分布情况
  19. uri (url)保存为jpg图片(文件)
  20. 荣耀接盘者传闻多多,但最可能接盘的是神州数码

热门文章

  1. linux设置send时间,[转]Socket 的send,recv在windows与linux下的超时设置
  2. java程序退出自动保存_你知道如何自动保存 Spring Boot 应用进程号吗
  3. 联想小新pro无法人脸识别自动开机的解决方法
  4. dnf超时空漩涡副本路线流程图_DNF超时空漩涡机制
  5. (组合数学笔记)Pólya计数理论_Part.10_Pólya定理的推广——De Bruijn定理的母函数形式
  6. python读取图片并储存为CSV文件
  7. SQL Server IS NULL语句使用举例
  8. 【maven配置】IDEA自动生成的pom文件报错:URI Is Not Registered
  9. windows下gvim8打开文件中文乱码处理
  10. Python练习:五到七章的练习题