Function
注意到u的绝对值小与10^5,但q小与5*10^5,肯定有重复的,直接预处理每个数的最大值,这样刚刚卡过去
这是大佬很神奇的做法
估值线段树
普通的线段树,记录maxa,maxb,maxc,minb比较左右儿子估算出来的值,先搜估值大的儿子,如果先搜的得到的ans<另一个儿子的估值,再搜另一个儿子,其实也算是暴力+剪枝
我打的比较丑,效率及其慢
#include<iostream> #include<cstring> #include<cstdio> //#include<map> #define maxn 1005 #define LL long long #define INF 100000 using namespace std; int n,q; struct node { LL a,b,c; }nod[maxn]; struct tree { int l,r; LL maxa,maxb,maxc; LL minb; }b[maxn*4]; //map<int ,long long> mp; LL ans[INF*2+5]; bool vis[INF*2+5]; LL read() { LL x=0,op=1; char ch=getchar(); if(ch=='-') op=-1; while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*op; } inline LL get(LL a,LL b, LL c,LL x) { return a*x*x+b*x+c; } inline LL max(LL x,LL y) { return x>y? x:y; } inline LL min(LL x,LL y) { return x<y? x:y; } inline void update(int z) { b[z].maxa=max(b[2*z].maxa,b[2*z+1].maxa); b[z].maxb=max(b[2*z].maxb,b[2*z+1].maxb); b[z].maxc=max(b[2*z].maxc,b[2*z+1].maxc); b[z].minb=min(b[2*z].minb,b[2*z+1].minb); } void build(int l,int r,int z) { b[z].l=l;b[z].r=r; if(l==r){ b[z].maxa=nod[l].a; b[z].maxb=b[z].minb=nod[l].b; b[z].maxc=nod[l].c; return ; } int mid=(l+r)/2; build(l,mid,2*z); build(mid+1,r,2*z+1); update(z); //printf("%d %d %lld %lld %lld\n",b[z].l,b[z].r,b[z].maxa,b[z].maxb,b[z].maxc); } LL quiry(int z,LL x) { LL ans=-0x7fffffff; if(b[z].l==b[z].r){ if(x>0) return b[z].maxa*x*x+b[z].maxb*x+b[z].maxc; else return b[z].maxa*x*x+b[z].minb*x+b[z].maxc; } LL t1,t2; if(x>0) t1=b[2*z].maxa*x*x+b[2*z].maxb*x+b[2*z].maxc; else t1=b[2*z].maxa*x*x+b[2*z].minb*x+b[2*z].maxc; if(x>0) t2=b[2*z+1].maxa*x*x+b[2*z+1].maxb*x+b[2*z+1].maxc; else t2=b[2*z+1].maxa*x*x+b[2*z+1].minb*x+b[2*z+1].maxc; if(t1>t2){ ans=quiry(2*z,x); if(t2>ans) ans=max(ans,quiry(2*z+1,x)); } else{ ans=quiry(2*z+1,x); if(t1>ans) ans=max(ans,quiry(2*z,x)); } return ans; } int main() { // freopen("function.in","r",stdin); // freopen("function.out","w",stdout); LL x; n=read();q=read(); for(int i=1;i<=n;i++) { nod[i].a=read();nod[i].b=read();nod[i].c=read(); } build(1,n,1); LL an; while(q--){ x=read(); if(vis[x+INF]) printf("%lld\n",ans[x+INF]); else{ ans[x+INF]=quiry(1,x); printf("%lld\n",ans[x+INF]); vis[x+INF]=ans[x+INF]; } } return 0; }