估值线段树
#include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> # define maxn 1010 using namespace std; typedef long long LL; int n,m; struct node{ LL a,b,c; }g[maxn]; struct Tree{ LL a,mxb,mnb,c; }tr[4*maxn]; int sc=0; LL Max(LL a,LL b){return a>b? a:b;} LL Min(LL a,LL b){return a<b? a:b;} void pushup(int rt){ int ls=rt<<1, rs=rt<<1|1; tr[rt].a=Max(tr[ls].a,tr[rs].a); tr[rt].mnb=Min(tr[ls].mnb,tr[rs].mnb); tr[rt].mxb=Max(tr[ls].mxb,tr[rs].mxb); tr[rt].c=Max(tr[ls].c,tr[rs].c); } void bds(int rt,int l,int r){ if(l==r){ tr[rt].a=g[l].a; tr[rt].mxb=tr[rt].mnb=g[l].b; tr[rt].c=g[l].c; return; } int mid=(l+r)>>1; bds(rt<<1,l,mid); bds(rt<<1|1,mid+1,r); pushup(rt); } LL ans; void zheng_find(int rt,int l,int r,LL x,LL y){ if(l==r){ ans=Max(ans,tr[rt].a*x+tr[rt].mxb*y+tr[rt].c); return; } int mid=(l+r)>>1,ls=rt<<1,rs=rt<<1|1; LL ans1=tr[ls].a*x+tr[ls].mxb*y+tr[ls].c; LL ans2=tr[rs].a*x+tr[rs].mxb*y+tr[rs].c; if(ans1 > ans2) { if(ans>ans1) return; zheng_find(rt<<1,l,mid,x,y); if(ans<ans2) zheng_find(rt<<1|1,mid+1,r,x,y); } else{ if(ans>ans2) return; zheng_find(rt<<1|1,mid+1,r,x,y); if(ans<ans1) zheng_find(rt<<1,l,mid,x,y); } } void fu_find(int rt,int l,int r,LL x,LL y){ if(l==r){ ans=Max(ans,tr[rt].a*x+tr[rt].mnb*y+tr[rt].c); return; } int mid=(l+r)>>1,ls=rt<<1,rs=rt<<1|1; LL ans1=tr[ls].a*x+tr[ls].mnb*y+tr[ls].c; LL ans2=tr[rs].a*x+tr[rs].mnb*y+tr[rs].c; if(ans1 > ans2){ if(ans>ans1) return; fu_find(rt<<1,l,mid,x,y); if(ans < ans2) fu_find(rt<<1|1,mid+1,r,x,y); } else { if(ans>ans2) return; fu_find(rt<<1|1,mid+1,r,x,y); if(ans < ans1) fu_find(rt<<1,l,mid,x,y); } } int main(){ //freopen("function.in","r",stdin); //freopen("function.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%lld%lld%lld",&g[i].a,&g[i].b,&g[i].c); bds(1,1,n); LL x; for(int i=1;i<=m;i++){ scanf("%lld",&x); ans=-0x7fffffffffffffffLL; if(x>=0) zheng_find(1,1,n,x*x,x); else fu_find(1,1,n,x*x,x); printf("%lld\n",ans); } return 0; }