• #6034. 「雅礼集训 2017 Day2」线段游戏 李超树


    #6034. 「雅礼集训 2017 Day2」线段游戏

    内存限制:256 MiB时间限制:1000 ms标准输入输出
    题目类型:传统评测方式:Special Judge
    上传者: 匿名

    题目描述

    给出若干条线段,用 (x1,y2),(x2,y2) (x_1, y_2), (x_2, y_2)(x1​​,y2​​),(x2​​,y2​​) 表示其两端点坐标,现在要求支持两种操作:

    • 0 x1 y1 x2 y2 表示加入一条新的线段 (x1,y2),(x2,y2) (x_1, y_2), (x_2, y_2)(x1​​,y2​​),(x2​​,y2​​);
    • 1 x0 询问所有线段中,x xx 坐标在 x0 x_0x0​​ 处的最高点的 y yy 坐标是什么,如果对应位置没有线段,则输出 0 00。

    输入格式

    第一行两个正整数 n nn、m mm 为初始的线段个数和操作个数。
    接下来 n nn 行,每行四个整数,表示一条线段。
    接下来 m mm 行,每行为一个操作 0 x1 y1 x2 y2 或 1 x0

    输出格式

    对于每一个询问操作,输出一行,为一个实数,当你的答案与标准答案误差不超过 10−2 10 ^ {-2}102​​ 时,则视为正确。

    样例

    样例输入

    3 4
    0 -1 4 1
    4 2 7 2
    7 1 8 2
    1 4
    1 3
    0 3 3 6 3
    1 3

    样例输出

    2
    0.5
    3

    对于线段树的每个节点,维护每个节点使得mid的值最大。
    对于不优的答案下传。查询时与标记永久化的查询类似。
    其实就是李超树。
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<algorithm>
     7 #define maxn 100005
     8 using namespace std;
     9 inline int read() {
    10     int x=0,f=1;char ch=getchar();
    11     for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
    12     for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    13     return x*f;
    14 }
    15 struct seg {double k,b;seg(){b=-10000000000000000;}}t[maxn*4];
    16 inline double cal(seg now,int x) {return now.k*x+now.b;}
    17 inline void work(int l,int r,int o,seg x) {
    18     if(cal(t[o],l)>=cal(x,l)&&cal(t[o],r)>=cal(x,r)) {return;}
    19     if(cal(t[o],l)<cal(x,l)&&cal(t[o],r)<cal(x,r)) {t[o]=x;return;}
    20     int mid=(l+r)>>1,ls=o<<1,rs=ls+1;
    21     if(cal(t[o],l)>=cal(x,l)&&cal(t[o],mid)<cal(x,mid)) {
    22         seg tmp=t[o];t[o]=x;
    23         work(l,mid,ls,tmp);
    24         return;
    25     }
    26     if(cal(t[o],l)>=cal(x,l)&&cal(t[o],mid)>cal(x,mid)) {
    27         if(l!=r) work(mid+1,r,rs,x);
    28         return;
    29     }
    30     if(cal(t[o],l)<cal(x,l)&&cal(t[o],mid)<cal(x,mid)) {
    31         seg tmp=t[o];t[o]=x;
    32         if(l!=r) work(mid+1,r,rs,tmp);
    33         return;
    34     }
    35     if(cal(t[o],l)<cal(x,l)&&cal(t[o],mid)>=cal(x,mid)) {
    36         if(l!=r) work(l,mid,ls,x);
    37         return;
    38     }
    39 }
    40 inline void update(int l,int r,int o,int L,int R,seg x) {
    41 //    cout<<l<<' '<<r<<endl;
    42     if(L<=l&&R>=r) {work(l,r,o,x);return;}
    43     int mid=(l+r)>>1,ls=o<<1,rs=ls+1;
    44     if(L<=mid) update(l,mid,ls,L,R,x);
    45     if(R>mid) update(mid+1,r,rs,L,R,x);
    46 }
    47 double ans;
    48 inline double query(int l,int r,int o,int x) {
    49     if(l==r) return cal(t[o],l);
    50     int mid=(l+r)>>1,ls=o<<1,rs=ls+1;
    51     if(x<=mid) return ans=max(ans,max(cal(t[o],x),query(l,mid,ls,x)));
    52     else return ans=max(ans,max(cal(t[o],x),query(mid+1,r,rs,x)));
    53 }
    54 int n,m;
    55 int main() {
    56     n=read(),m=read();
    57     for(int i=1;i<=n;i++) {
    58         int x1=read(),y1=read(),x2=read(),y2=read();
    59         if(x1>x2) {swap(x1,x2);swap(y1,y2);}
    60         if(x2<1||x1>100000) continue;
    61         seg x;
    62         if(x1==x2) x.k=0,x.b=max(y1,y2);
    63         else {
    64             x.k=(double)(y2-y1)/(double)(x2-x1);
    65             x.b=y1-x.k*x1;
    66         }
    67         update(1,100000,1,max(1,x1),min(100000,x2),x);
    68     }
    69     while(m--) {
    70         int tp=read();
    71         if(tp==0) {
    72             int x1=read(),y1=read(),x2=read(),y2=read();
    73             if(x1>x2) {swap(x1,x2);swap(y1,y2);}
    74             if(x2<1||x1>100000) continue;
    75             seg x;
    76             if(x1==x2) x.k=0,x.b=max(y1,y2);
    77             else {
    78                 x.k=(double)(y2-y1)/(double)(x2-x1);
    79                 x.b=y1-x.k*x1;
    80             }
    81             update(1,100000,1,max(1,x1),min(100000,x2),x);
    82         }
    83         else {
    84             int x=read();ans=-10000000000000000;
    85             query(1,100000,1,x);
    86             printf("%.3lf
    ",ans==-10000000000000000?0:ans);
    87         }
    88     }
    89 }
    View Code
     
  • 相关阅读:
    iOS image.size大小实际输出的值跟图片像素的关系
    iOS 记录蓝牙传输相关进制转换/字节转换/NSData转换/大小端转换
    Objective-C 中Socket常用转换机制(NSData,NSString,int,Uint8,Uint16,Uint32,byte[])
    ios-如何将UIColor RGB颜色转换为uint32_t值
    iOS 多国语言判断
    android 通过WIFI调试和adb指令推送文件到安卓设备
    iOS ViewController跳转界面的几种方法简单总结
    整理汇总能够提升文字工作效率的工具app分享给大家
    js 把字符串转换成数组,数组去重后再转成字符串
    我和朋友写的《Go语言从基础到中台微服务实战开发》已出版在京东,当当上可以购买了
  • 原文地址:https://www.cnblogs.com/wls001/p/9643019.html
Copyright © 2020-2023  润新知