zoukankan      html  css  js  c++  java
  • [校内训练19_09_02]A

    题意

    给出N 个形如$f_i(x) = a_i x^2 + b_i x $的二次函数。

    有Q 次询问,每次给出一个x,询问$max{{f_i(x)}}$。$N,Q leq 5*10^5$。


    思考

    首先将x大于0还是小于0分类,对于某一类全都除以x,那么就得到了一些直线。最优的答案一定在某条最上方或最下方的直线上,半平面交或凸包即可。


    代码

      1 // luogu-judger-enable-o2
      2 #pragma GCC optimize 2
      3 #include<bits/stdc++.h>
      4 using namespace std;
      5 typedef long long int ll;
      6 typedef long double ld;
      7 const int maxn=5E5+5;
      8 const int base=33333;
      9 const ld eps=1E-10;
     10 const ld inf=1E17;
     11 int n,m,T;
     12 ll a[maxn],b[maxn],ans[maxn];
     13 int idR[maxn],idL[maxn];
     14 ld rightPlane[maxn],leftPlane[maxn];
     15 int q[maxn];
     16 struct pt
     17 {
     18     double x,y;
     19     pt(double a=0,double b=0):x(a),y(b){}
     20     pt operator+(const pt&A){return pt(x+A.x,y+A.y);}
     21     pt operator-(const pt&A){return pt(x-A.x,y-A.y);}
     22     pt operator*(ld d){return pt(x*d,y*d);}
     23     double operator*(const pt&A){return x*A.y-y*A.x;}
     24     void out(){cout<<"("<<x<<","<<y<<")"<<endl;}
     25 };
     26 struct line
     27 {
     28     pt A,B;
     29     int id,b;
     30     int slope;
     31     line(){}
     32     line(pt a,pt b):A(a),B(b){}
     33 }s[maxn];
     34 inline ll max(ll x,ll y)
     35 {
     36     return x>y?x:y;
     37 }
     38 inline ll min(ll x,ll y)
     39 {
     40     return x<y?x:y;
     41 }
     42 inline ll get(ll x,ll a,ll b)
     43 {
     44     return (a*x+b)*x;
     45 }
     46 inline int read()
     47 {
     48     bool flag=0;
     49     char ch=getchar();
     50     if(ch=='-')
     51         flag^=1;
     52     while(!isdigit(ch))
     53     {
     54         ch=getchar();
     55         if(ch=='-')
     56             flag^=1;
     57     }
     58     int sum=ch-'0';
     59     ch=getchar();
     60     while(isdigit(ch))
     61     {
     62         sum=sum*10+ch-'0';
     63         ch=getchar();
     64     }
     65     return flag?-sum:sum;
     66 }
     67 void write(ll x)
     68 {
     69     if(x>=10)
     70         write(x/10);
     71     putchar('0'+x%10);
     72 }
     73 inline void writen(ll x)
     74 {
     75     if(x<0)
     76     {
     77         putchar('-');
     78         write(-x);
     79     }
     80     else
     81         write(x);
     82     putchar('
    ');
     83 }
     84 inline int cross(pt A,pt B)
     85 {
     86     ld d=A*B;
     87     if(abs(d)<=eps)
     88         return 0;
     89     return d>0?1:-1;
     90 }
     91 inline pt intersection(line a,line b)
     92 {
     93     pt A=b.B-b.A,B=a.B-a.A,C=b.A-a.A;
     94     if(cross(A,B)==0)
     95         return pt(inf,inf);
     96     ld d=-(B*C)/(B*A);
     97     return b.A+A*d;
     98 }
     99 inline int onClockwise(line a,line b,line c)
    100 {
    101     return cross(a.B-a.A,intersection(b,c)-a.A)==-1;
    102 }
    103 bool cmpR(line A,line B)
    104 {
    105     if(A.slope==B.slope)
    106         return A.b<B.b;
    107     return A.slope<B.slope;
    108 }
    109 bool cmpL(line A,line B)
    110 {
    111     if(A.slope==B.slope)
    112         return A.b>B.b;
    113     return A.slope<B.slope;
    114 }
    115 void initR()
    116 {
    117     sort(s+1,s+n+1,cmpR);
    118     int L=1,R=0;
    119     for(int i=1;i<=n;++i)
    120     {
    121         while(i!=n&&s[i].slope==s[i+1].slope)
    122             ++i;
    123         while(R-1>=L&&onClockwise(s[i],s[q[R]],s[q[R-1]]))
    124             --R;
    125         q[++R]=i;
    126     }
    127     for(int i=1;i<=R;++i)
    128         idR[i]=s[q[i]].id;
    129     for(int i=1;i<R;++i)
    130         rightPlane[i]=intersection(s[q[i]],s[q[i+1]]).x;
    131     int pos=1;
    132     for(int i=-base;i<=base;++i)
    133     {
    134         while(pos<R&&rightPlane[pos]<ld(i))
    135             ++pos;
    136         ans[i+base]=get(i,s[q[pos]].slope,s[q[pos]].b);
    137     }
    138 }
    139 void initL()
    140 {
    141     sort(s+1,s+n+1,cmpL);
    142     int L=1,R=0;
    143     for(int i=1;i<=n;++i)
    144     {
    145         while(i!=n&&s[i].slope==s[i+1].slope)
    146             ++i;
    147         while(R-1>=L&&onClockwise(s[i],s[q[R]],s[q[R-1]]))
    148             --R;
    149         q[++R]=i;
    150     }
    151     for(int i=1;i<=R;++i)
    152         idL[i]=s[q[i]].id;
    153     for(int i=1;i<R;++i)
    154         leftPlane[i]=intersection(s[q[i]],s[q[i+1]]).x;
    155     int pos=1;
    156     for(int i=base;i>=-base;--i)
    157     {
    158         while(pos<R&&ld(i)<leftPlane[pos])
    159             ++pos;
    160         ans[i+base]=max(ans[i+base],get(i,s[q[pos]].slope,s[q[pos]].b));
    161     }
    162 }
    163 int main()
    164 {
    165 //    freopen("A.in","r",stdin);
    166 //    freopen("A.out","w",stdout);
    167     ios::sync_with_stdio(false);
    168     n=read(),T=read();
    169     for(int i=1;i<=n;++i)
    170     {
    171         a[i]=read(),b[i]=read();
    172         s[i].A=pt(0,b[i]);
    173         s[i].B=pt(1,a[i]+b[i]);
    174         s[i].slope=a[i];
    175         s[i].b=b[i];
    176         s[i].id=i;
    177     }
    178     initR();
    179     for(int i=1;i<=n;++i)
    180         swap(s[i].A,s[i].B);
    181     initL();
    182     while(T--)
    183     {
    184         int x=read();
    185         writen(ans[x+base]);
    186     }
    187     return 0;
    188 }
    View Code
  • 相关阅读:
    Google I/O 官方应用中的动效设计
    浪院长 | spark streaming的使用心得
    Kubernetes 1.12公布:Kubelet TLS Bootstrap与Azure虚拟机规模集(VMSS)迎来通用版本号
    安卓自己定义View进阶-Path基本操作
    2014编程之美初赛第二场
    2015年,即将结束
    查看JVM运行时参数
    使用ThreadPoolExecutor线程池实现并发操作并返回结果
    mysql数据库将查询的多条结果的某些字段合并为一个字段处理
    mysql数据库使用mybatis新增操作返回自增主键的值
  • 原文地址:https://www.cnblogs.com/GreenDuck/p/11553621.html
Copyright © 2011-2022 走看看