zoukankan      html  css  js  c++  java
  • BZOJ 3165: [Heoi2013]Segment

    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

      1 #include <bits/stdc++.h>
      2 
      3 struct line
      4 {
      5     int lt, rt;
      6     double k, b;
      7     
      8     line(void) {};
      9     
     10     line(int x0, int y0, int x1, int y1)
     11     {
     12         if (x0 < x1)
     13             lt = x0, rt = x1;
     14         else
     15             lt = x1, rt = x0;
     16         
     17         if (x0 == x1)
     18         {
     19             k = 0.0;
     20             b = y0 > y1 ? y0 : y1;
     21         }
     22         else
     23         {
     24             k = 1.0 * (y0 - y1) / (x0 - x1);
     25             b = y0 - x0 * k;
     26         }
     27     }
     28     
     29     inline double f(int x)
     30     {
     31         return k * x + b;
     32     }
     33 }ln[100005]; int tot;
     34 
     35 int sg(double x)
     36 {
     37     static const double eps = 1e-10;
     38     
     39     return (x > -eps) - (x < +eps);
     40 }
     41 
     42 int cross(int i, int j)
     43 {
     44     return floor((ln[i].b - ln[j].b) / (ln[j].k - ln[i].k));
     45 }
     46 
     47 int flg[160005];
     48 
     49 int wi[40005]; double wy[40005];
     50 
     51 inline void update(int x, int p)
     52 {
     53     double y = ln[p].f(x);
     54     
     55     int s = sg(y - wy[x]);
     56     
     57     if (!wi[x] || s > 0 || (!s && p < wi[x]))
     58         wi[x] = p, wy[x] = y;
     59 }
     60 
     61 void insert(int t, int l, int r, int p)
     62 {
     63     if (ln[p].lt <= l && ln[p].rt >= r)
     64     {
     65         if (!flg[t])flg[t] = p;
     66         else
     67         {
     68             int mid = (l + r) >> 1;
     69             
     70             bool lu = sg(ln[p].f(l) - ln[flg[t]].f(l)) > 0;
     71             bool ru = sg(ln[p].f(r) - ln[flg[t]].f(r)) > 0;
     72             
     73             if (lu && ru)flg[t] = p;
     74             else if (lu || ru)
     75             {
     76                 int tt = cross(p, flg[t]);
     77                 if (tt <= mid)
     78                 {
     79                     if (lu)
     80                         insert(t << 1, l, mid, p);
     81                     else
     82                         insert(t << 1, l, mid, flg[t]), flg[t] = p;
     83                 }
     84                 else
     85                 {
     86                     if (ru)
     87                         insert(t << 1 | 1, mid + 1, r, p);
     88                     else
     89                         insert(t << 1 | 1, mid + 1, r, flg[t]), flg[t] = p;
     90                 }
     91             }
     92             else
     93             {
     94                 update(l, p);
     95                 update(r, p);
     96             }
     97         }
     98     }
     99     else
    100     {
    101         int mid = (l + r) >> 1;
    102         
    103         if (ln[p].lt <= mid)
    104             insert(t << 1, l, mid, p);
    105         if (ln[p].rt > mid)
    106             insert(t << 1 | 1, mid + 1, r, p);
    107     }
    108 }
    109 
    110 int ansi; double ansy;
    111 
    112 void query(int t, int l, int r, int x)
    113 {
    114     if (flg[t])
    115     {
    116         double y = ln[flg[t]].f(x);
    117         
    118         int s = sg(y - ansy);
    119         
    120         if (s > 0 || (!s && flg[t] < ansi))
    121             ansi = flg[t], ansy = y;
    122     }
    123     
    124     if (l != r)
    125     {
    126         int mid = (l + r) >> 1;
    127         
    128         if (x <= mid)
    129             query(t << 1, l, mid, x);
    130         if (x > mid)
    131             query(t << 1 | 1, mid + 1, r, x);
    132     }
    133 }
    134 
    135 signed main(void)
    136 {
    137     int n; scanf("%d", &n);
    138     
    139     for (int ans = 0; n--; )
    140     {
    141         int op; scanf("%d", &op);
    142         
    143         if (op)    // insert segment
    144         {
    145             int x0, y0, x1, y1;
    146             
    147             scanf("%d%d%d%d", &x0, &y0, &x1, &y1);
    148             
    149             x0 = (x0 + ans - 1) % 39989 + 1;
    150             x1 = (x1 + ans - 1) % 39989 + 1;
    151             y0 = (y0 + ans - 1) % 1000000000 + 1;
    152             y1 = (y1 + ans - 1) % 1000000000 + 1;
    153             
    154             ln[++tot] = line(x0, y0, x1, y1);
    155             
    156             insert(1, 1, 40000, tot);
    157         }
    158         else    // query segment
    159         {
    160             int x; scanf("%d", &x);
    161             
    162             x = (x + ans - 1) % 39989 + 1;
    163             
    164             ansi = wi[x], ansy = wy[x];
    165             
    166             query(1, 1, 40000, x);
    167             
    168             printf("%d
    ", ans = ansi);
    169         }
    170     }
    171 }

    @Author: YouSiki

  • 相关阅读:
    二进制状态压缩对应 bool 数组中的常用操作
    [Acwing 327] 玉米田 题解
    [CF Contest] Web of Lies 题解
    ArchLinux安装vscode
    ArchLinux安装并且配置fcitx5
    【日常训练】取数问题
    Oracle sql 转 Hive sql一些语法问题
    Oracle中的connect by 转成hive的 lateral view explode
    Hive之分析函数
    数据仓库之拉链表设计
  • 原文地址:https://www.cnblogs.com/yousiki/p/6293455.html
Copyright © 2011-2022 走看看