洛谷 P4097 [HEOI2013]Segment 解题报告
P4097 [HEOI2013]Segment
题目描述
要求在平面直角坐标系下维护两个操作:
- 在平面上加入一条线段。记第 \(i\) 条被插入的线段的标号为 \(i\)
- 给定一个数 \(k\),询问与直线 \(x = k\) 相交的线段中,交点最靠上的线段的编号。
输入输出格式
输入格式:
第一行一个整数 \(n\),表示共 \(n\) 个操作
接下来 \(n\) 行,每行第一个数为 \(0\) 或 \(1\)
若该数为 \(0\),则后面跟着一个正整数 \(k\),表示询问与直线 \(x = ((k + lastans – 1)\%39989+1)\)相交的线段中交点(包括在端点相交的情形)最靠上的线段的编号,其中\(\%\)表示取余。若某条线段为直线的一部分,则视作直线与线段交于该线段 \(y\) 坐标最大处。若有多条线段符合要求,输出编号最小的线段的编号
若该数为 \(1\),则后面跟着四个正整数 \(x_0, y_0, x_1, y_1\),表示插入一条两个端点为 \(((x_0+lastans-1)\%39989+1\),\((y_0+lastans-1)%10^9+1)\)和 \(((x_1+lastans-1)%39989+1,(y1+lastans-1)\%10^9+1)\) 的线段
其中 \(lastans\) 为上一次询问的答案。初始时 \(lastans=0\)
输出格式:
对于每个 \(0\) 操作,输出一行,包含一个正整数,表示交点最靠上的线段的编 号。若不存在与直线相交的线段,答案为 \(0\)
说明
对于\(30\%\)的数据,\(n ≤ 1000\)
对于\(100\%\)的数据,\(1 ≤ n ≤ 10^5, 1 ≤ k, x_0, x_1 ≤ 39989, 1 ≤ y_0 ≤ y_1 ≤ 10^9\)
李超线段树
对\(x\)建线段树,每个区间存一个线段进行标记永久化。
这个线段用斜截式子\(k,b\)保存
当查询时,遍历的时候拿所有的节点进行更新。
当修改时,当完全覆盖当前区间时
如果这个区间还没有线段,占上去
如果这个区间上的线段和当前线段在此段无交点,选择上面的一个保留
判断交点在\(mid\)左边还是右边
以在左边为例
如果当前左端点>区间左端点,当前区间保留,自己进左儿子去更新
否则把自己留着这,把当前区间的踹下去
右边同理
因为每个线段最多被划分成\(\log n\)段,所以复杂度是\(O(n\log^2 n)\)的
Code:
#include <cstdio>
#include <algorithm>
#include <cmath>
using std::max;
const int N=1e5+10;
int n=39989,m;
struct seg
{
double k,b;
int id;
seg(){}
seg(int x,int y,int xx,int yy,int Id)
{
k=1.0*(yy-y)/(1.0*(xx-x));
b=y-k*x;
id=Id;
}
double pos(double x){return k*x+b;}
}mx[N<<2];
const double eps=1e-5;
bool dcmp(double x,double y){return fabs(x-y)<eps;}
struct beecute
{
int id;double mx;
beecute(){}
beecute(int Id,double Mx){id=Id,mx=Mx;}
bool friend operator <(beecute a,beecute b){return dcmp(a.mx,b.mx)?a.id>b.id:a.mx<b.mx;}
}bee[N],las;
#define ls id<<1
#define rs id<<1|1
void change(int id,int L,int R,int l,int r,seg ins)
{
int Mid=L+R>>1;
if(l==L&&r==R)
{
if(!mx[id].id) {mx[id]=ins;return;}
double a=ins.pos(1.0*l),b=ins.pos(1.0*r),c=mx[id].pos(1.0*l),d=mx[id].pos(1.0*r);
if(a>c&&b>d) {mx[id]=ins;return;}
if(a<c&&b<d) return;
double x=(mx[id].b-ins.b)/(ins.k-mx[id].k);
if((double)(Mid)<x)
{
if(a>c)
{
change(rs,Mid+1,R,Mid+1,r,mx[id]);
mx[id]=ins;
}
else change(rs,Mid+1,R,Mid+1,r,ins);
}
else
{
if(a>c) change(ls,L,Mid,l,Mid,ins);
else
{
change(ls,L,Mid,l,Mid,mx[id]);
mx[id]=ins;
}
}
return;
}
if(r<=Mid) change(ls,L,Mid,l,r,ins);
else if(l>Mid) change(rs,Mid+1,R,l,r,ins);
else change(ls,L,Mid,l,Mid,ins),change(rs,Mid+1,R,Mid+1,r,ins);
}
void query(int id,int l,int r,int p,beecute &ret)
{
if(mx[id].id) ret=max(ret,beecute(mx[id].id,mx[id].pos(1.0*p)));
if(l==r) return;
int mid=l+r>>1;
if(p<=mid) query(ls,l,mid,p,ret);
else query(rs,mid+1,r,p,ret);
}
int main()
{
scanf("%d",&m);
for(int id=0,op,k,a,b,c,d,i=1;i<=m;i++)
{
scanf("%d",&op);
if(op)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
a=(a+las.id-1)%n+1,b=(b+las.id-1)%(int)(1e9)+1;
c=(c+las.id-1)%n+1,d=(d+las.id-1)%(int)(1e9)+1;
if(a>c) std::swap(a,c),std::swap(b,d);
if(a==c) bee[a]=max(bee[a],beecute(++id,1.0*max(b,d)));
else change(1,1,n,a,c,seg(a,b,c,d,++id));
}
else
{
scanf("%d",&k);
k=(k+las.id-1)%n+1;
las=bee[k];
query(1,1,n,k,las);
printf("%d\n",las.id);
}
}
return 0;
}
2019.2.14
洛谷 P4097 [HEOI2013]Segment 解题报告的更多相关文章
- 2018.07.23 洛谷P4097 [HEOI2013]Segment(李超线段树)
传送门 给出一个二维平面,给出若干根线段,求出x" role="presentation" style="position: relative;"&g ...
- 洛谷P4097 [HEOI2013]Segment(李超线段树)
题面 传送门 题解 调得咱自闭了-- 不难发现这就是个李超线段树,不过因为这里加入的是线段而不是直线,所以得把线段在线段树上对应区间内拆开之后再执行李超线段树的操作,那么复杂度就是\(O(n\log^ ...
- [洛谷P4097] [HEOI2013] Segment
Description 要求在平面直角坐标系下维护两个操作: 1.在平面上加入一条线段.记第 \(i\) 条被插入的线段的标号为 \(i\) 2.给定一个数 \(k\) ,询问与直线 \(x = k\ ...
- 洛谷 P1783 海滩防御 解题报告
P1783 海滩防御 题目描述 WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭 ...
- 洛谷 P4597 序列sequence 解题报告
P4597 序列sequence 题目背景 原题\(\tt{cf13c}\)数据加强版 题目描述 给定一个序列,每次操作可以把某个数\(+1\)或\(-1\).要求把序列变成非降数列.而且要求修改后的 ...
- 洛谷1087 FBI树 解题报告
洛谷1087 FBI树 本题地址:http://www.luogu.org/problem/show?pid=1087 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全 ...
- 洛谷 P3349 [ZJOI2016]小星星 解题报告
P3349 [ZJOI2016]小星星 题目描述 小\(Y\)是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有\(n\)颗小星星,用\(m\)条彩色的细线串了起来,每条细线连着两颗小星星. 有一 ...
- 洛谷 P3177 树上染色 解题报告
P3177 [HAOI2015]树上染色 题目描述 有一棵点数为\(N\)的树,树边有边权.给你一个在\(0\) ~ \(N\)之内的正整数\(K\),你要在这棵树中选择\(K\)个点,将其染成黑色, ...
- 洛谷 P4705 玩游戏 解题报告
P4705 玩游戏 题意:给长为\(n\)的\(\{a_i\}\)和长为\(m\)的\(\{b_i\}\),设 \[ f(x)=\sum_{k\ge 0}\sum_{i=1}^n\sum_{j=1}^ ...
随机推荐
- Luogu P3327 [SDOI2015]约数个数和
又是恶心的莫比乌斯反演,蒟蒻我又是一脸懵逼的被CXR dalao狂虐. 题目要求\(ans=\sum_{i=1}^n \sum_{j=1}^m d(ij)\),其中\(d(ij)\)表示数\(x\)的 ...
- [JSOI2016]无界单词[动态规划、kmp]
题意 题目链接 分析 对于第一问,枚举最终串最小的相同前后缀来统计答案. 由于最小的相同前后缀也是无界单词,所以可以考虑先求解子问题. 定义状态 \(f(i)\) 表示长度为 \(i\) 的串中有多少 ...
- 硬编码转换单位||vue
//测试单位 formatUnit:function (id) { var val; switch(id){ case 4: return val="圈" break; } } / ...
- Github介绍
Git是一个分布式的版本控制系统,最初由LinusTorvalds编写,用作Linux内核代码的管理.在推出后,Git在其它项目中也取得了很大成功,尤其是在Ruby社区中.包括Rubinius和Mer ...
- 理解java的三大特性之继承
学习来源:http://www.cnblogs.com/chenssy/p/3354884.html default 默认权限(包权限-同一个包可以访问) private 私有(类内部可以使用,继承的 ...
- Python轻松爬取Rosimm写真网站全部图片
RosimmImage 爬取Rosimm写真网站图片 有图有真相 def main_start(url): """ 爬虫入口,主要爬取操作 ""&qu ...
- vue js 在组件中对数组使用splice() 遇到的坑。。。
遇到的问题: 用el-dialog写了个子组件 要实现在子组件中增删数据 点击确定后把值返回给父组件 父组件在每次点开子组件时都会把自己的值传进去. //父组件传值 this.$refs.transf ...
- PAT 1056 组合数的和
https://pintia.cn/problem-sets/994805260223102976/problems/994805271455449088 给定 N 个非 0 的个位数字,用其中任意 ...
- Disabling Chrome cache for website development
https://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development https://s ...
- App WebView实例化
a,高级设置里的环境变量 jdk的配置 b,下载Google的sdk,里面直接包含eclipse 1,新建一个项目 2,起个名字 3,设么走不做,next 4,只操作选择显示的三种方式 5,next什 ...