连夜补博客
ZJ:
看见T1就自闭了。(高考数学)(但是好像不是)
三个暴力就结束了。
35
|
Miemeng | 20
00:00:41
|
10
00:00:41
|
10
00:00:41
|
40
00:00:41
|
TJ:
T1
又是凸包凹包口包吕包旧包巨包
那么我们先看下函数$f(x)=a x^2 + b x$
这函数好啊。
都过原点。
然鹅并没有用,
好象还是有点用的。
我们考虑化柿子(话说这玩意有什么柿子可说)
$a_1 x^2+b_1x < a_2 x^2 + b_2 x$
那么就可以分情况讨论了,
$x>0 , a_1 x + b_1 < a_2 x + b_2 $
$x<0 , a_1 x + b_1 > a_2 x + b_2 $
$x=0$直接输出$0$
我们发现可以用一条直线来‘代表’这个二次函数。
于是求$x>0$时的下凸包,$x>0$时的上凸包。
细节较多,尤其是……
还是见代码吧。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #define N 555555 #define LL long long #define LF long double #define ans(k) ans[(k)+44444] using namespace std; int ln,qn; struct Lines{ LL ar,br; LL fig(LL x){ return ar*x*x+br*x; } }ps[N]; template <typename T> class Mystack{ T A[N*10]; public: int tp; Mystack(){tp=0;} T& operator [](const int id){return A[id];} bool empty(){return tp==0;} int size(){return tp;} void clear(){tp=0;} void push(const T k){A[tp++]=k;} T top(){return A[tp-1];} T ttop(){return A[tp-2];} void pop(){tp--;} void pour(){ puts("Stack:"); for(int i=0;i<tp;i++) cout<<A[i].ar<<" "<<A[i].br<<endl; puts("---------"); } }; Mystack <Lines> st1,st2; LL ans[N]; bool CMP1(const Lines &a,const Lines &b){ return a.ar==b.ar?a.br<b.br:a.ar<b.ar; } bool CMP2(const Lines &a,const Lines &b){ return a.ar==b.ar?a.br>b.br:a.ar<b.ar; } LF jud(Lines a,Lines b){ return 1.0l*(b.br-a.br)/(a.ar-b.ar); } int main(){ #ifndef LOCAL freopen("A.in" ,"r",stdin ); freopen("A.out","w",stdout); #endif int a; scanf("%d%d",&ln,&qn); for(int i=1;i<=ln;i++){ scanf("%lld%lld",&ps[i].ar,&ps[i].br); } sort(ps+1,ps+ln+1,CMP1); for(int i=1;i<=ln;i++){ while(!st1.empty() && ps[i].ar==st1.top().ar) st1.pop(); while(st1.size()>=2 && jud(st1.top(),st1.ttop()) >= jud(ps[i],st1.ttop())) st1.pop(); st1.push(ps[i]); } int j=0; for(int i=1;i<44444;i++){ while(j<st1.tp-1 && jud(st1[j],st1[j+1])<=1.*i)j++; ans(i)=st1[j].fig(i); } sort(ps+1,ps+ln+1,CMP2); for(int i=1;i<=ln;i++){ while(!st2.empty() && ps[i].ar==st2.top().ar) st2.pop(); while(st2.size()>=2 && jud(st2.top(),st2.ttop()) <= jud(ps[i],st2.ttop())) st2.pop(); st2.push(ps[i]); } j=0; for(int i=-1;i>-44444;i--){ while(j<st2.tp-1 && jud(st2[j],st2[j+1])>=1.*i)j++; ans(i)=st2[j].fig(i); } for(int i=1;i<=qn;i++){ scanf("%d",&a); printf("%lld ",ans(a)); } }