3165: [Heoi2013]Segment

Time Limit: 40 Sec  Memory Limit: 256 MB
Submit: 465  Solved: 187
[Submit][Status][Discuss]

Description

要求在平面直角坐标系下维护两个操作: 
1.在平面上加入一条线段。记第i条被插入的线段的标号为i。 
2.给定一个数k,询问与直线 x = k相交的线段中,交点最靠上的线段的编号。

Input

第一行一个整数n,表示共n 个操作。 
接下来n行,每行第一个数为0或1。 
 
若该数为 0,则后面跟着一个正整数 k,表示询问与直线  
x = ((k +lastans–1)%39989+1)相交的线段中交点(包括在端点相交的情形)最靠上的线段的编号,其中%表示取余。若某条线段为直线的一部分,则视作直线与线段交于该线段y坐标最大处。若有多条线段符合要求,输出编号最小的线段的编号。 
若该数为 1,则后面跟着四个正整数 x0, y0, x 1, y 1,表示插入一条两个端点为 
((x0+lastans-1)%39989+1,(y0+lastans-1)%10^9+1)和((x
1+lastans-1)%39989+1,(y1+lastans-1)%10^9+1) 的线段。 
其中lastans为上一次询问的答案。初始时lastans=0。

Output

对于每个 0操作,输出一行,包含一个正整数,表示交点最靠上的线段的编号。若不存在与直线相交的线段,答案为0。

Sample Input

6
1 8 5 10 8
1 6 7 2 6
0 2
0 9
1 4 7 6 7
0 5

Sample Output

2
0 3

HINT

对于100%的数据,1 ≤ n ≤ 10^5 , 1 ≤  k, x0, x1 ≤ 39989, 1 ≤ y0 ≤ y1 ≤ 10^9。

Source

 

[Submit][Status][Discuss]

HOME Back

线段树维护线段,23333

 #include <bits/stdc++.h>

 struct line
{
int lt, rt;
double k, b; line(void) {}; line(int x0, int y0, int x1, int y1)
{
if (x0 < x1)
lt = x0, rt = x1;
else
lt = x1, rt = x0; if (x0 == x1)
{
k = 0.0;
b = y0 > y1 ? y0 : y1;
}
else
{
k = 1.0 * (y0 - y1) / (x0 - x1);
b = y0 - x0 * k;
}
} inline double f(int x)
{
return k * x + b;
}
}ln[]; int tot; int sg(double x)
{
static const double eps = 1e-; return (x > -eps) - (x < +eps);
} int cross(int i, int j)
{
return floor((ln[i].b - ln[j].b) / (ln[j].k - ln[i].k));
} int flg[]; int wi[]; double wy[]; inline void update(int x, int p)
{
double y = ln[p].f(x); int s = sg(y - wy[x]); if (!wi[x] || s > || (!s && p < wi[x]))
wi[x] = p, wy[x] = y;
} void insert(int t, int l, int r, int p)
{
if (ln[p].lt <= l && ln[p].rt >= r)
{
if (!flg[t])flg[t] = p;
else
{
int mid = (l + r) >> ; bool lu = sg(ln[p].f(l) - ln[flg[t]].f(l)) > ;
bool ru = sg(ln[p].f(r) - ln[flg[t]].f(r)) > ; if (lu && ru)flg[t] = p;
else if (lu || ru)
{
int tt = cross(p, flg[t]);
if (tt <= mid)
{
if (lu)
insert(t << , l, mid, p);
else
insert(t << , l, mid, flg[t]), flg[t] = p;
}
else
{
if (ru)
insert(t << | , mid + , r, p);
else
insert(t << | , mid + , r, flg[t]), flg[t] = p;
}
}
else
{
update(l, p);
update(r, p);
}
}
}
else
{
int mid = (l + r) >> ; if (ln[p].lt <= mid)
insert(t << , l, mid, p);
if (ln[p].rt > mid)
insert(t << | , mid + , r, p);
}
} int ansi; double ansy; void query(int t, int l, int r, int x)
{
if (flg[t])
{
double y = ln[flg[t]].f(x); int s = sg(y - ansy); if (s > || (!s && flg[t] < ansi))
ansi = flg[t], ansy = y;
} if (l != r)
{
int mid = (l + r) >> ; if (x <= mid)
query(t << , l, mid, x);
if (x > mid)
query(t << | , mid + , r, x);
}
} signed main(void)
{
int n; scanf("%d", &n); for (int ans = ; n--; )
{
int op; scanf("%d", &op); if (op) // insert segment
{
int x0, y0, x1, y1; scanf("%d%d%d%d", &x0, &y0, &x1, &y1); x0 = (x0 + ans - ) % + ;
x1 = (x1 + ans - ) % + ;
y0 = (y0 + ans - ) % + ;
y1 = (y1 + ans - ) % + ; ln[++tot] = line(x0, y0, x1, y1); insert(, , , tot);
}
else // query segment
{
int x; scanf("%d", &x); x = (x + ans - ) % + ; ansi = wi[x], ansy = wy[x]; query(, , , x); printf("%d\n", ans = ansi);
}
}
}

@Author: YouSiki

最新文章

  1. swift基础:第三部分:对第一部分的补充说明
  2. OAM
  3. hibernate4中取得connection的方法
  4. 数迹学——Asp.Net MVC4入门指南(2):添加一个控制器
  5. [iOS翻译]《iOS7 by Tutorials》系列:在Xcode 5里使用单元测试(上)
  6. Express创建并运行node项目(Jade和EJS模版引擎)
  7. JSP01
  8. css透明(支持各浏览器)
  9. JIRA的常用选项
  10. 【BZOJ1861】【splay】Book 书架
  11. mobile&amp;nbsp;web&amp;nbsp;手机开发
  12. Directx11学习笔记【一】 最简单的windows程序HelloWin
  13. 51nod_1122:机器人走方格 V4 (矩阵快速幂)
  14. Linux Ubuntu jdk(环境变量)配置
  15. MongoDB 复制篇
  16. machine learning 之 Anomaly detection
  17. 美团分布式服务通信框架及服务治理系统OCTO
  18. redis的编译安装
  19. Vue/Egg大型项目开发(一)搭建项目
  20. mysql 查询正在执行的进程-亲试ok

热门文章

  1. 【Unity Shader】(五) ------ 透明效果之半透明效果的实现及原理
  2. Unity扩展编辑器二
  3. Unity学习笔记(3):一些常用API和应用场景
  4. 4. 为HelloWorld添加日志
  5. phpcms 容许英文目录有空格
  6. 欧拉筛——$O(n)$复杂度的质数筛法
  7. pwd命令详解
  8. 如何在静态方法或非Spring Bean中注入Spring Bean
  9. MathExam作业
  10. JAVA实验报告三:敏捷开发与XP实践