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;
}


posted @ 2017-08-11 06:33  HunterxHunterl  阅读(127)  评论(0编辑  收藏  举报