首页 > 代码库 > [HZOJ10420]计算
[HZOJ10420]计算
[HZOJ10420]计算
题目
给定一个数列,第i个位置包含两个数ai,bi
每次询问给出x,y
求数列ai*x+bi*y的最大值
输入所有数为自然数,在int范围内
INPUT
第一行为n,m。n为数列长度,m为询问个数。
接下来n行,每行两个数,代表ai,bi
接下来m行,每行两个数,代表x,y
OUTPUT
共m行,每行输出一个答案
SAMPLE
INPUT
3 3
1 5
9 0
9 1
4 4
1 1
3 4
OUTPUT
40
10
31
解题报告
首道估值线段树留念
首先,我们看题目,输入所有数据为自然数,自然数意味着不会有负数,那么,我们就可以确定,$a$和$b$越大,答案也就可能越大
剩下的就是如何找到准确的最大值了
我们可以用线段树处理出来每个区间的最大的$a$和$b$,然后,对于每一个询问,我们在线段树中进行搜索,我们可以用这个区间最大的$a$和$b$来限制搜索的范围,具体做法:
对于每一次搜索,我们先瞎XX搜到某一个子节点(一般来说是第一个子节点,根据线段树的实现而定),获得一个准确的$ans$值,然后,我们在搜索的时候,假如获得的该区间最大的$a$和$b$所计算出来的函数值都没有当前的$ans$大,我们可以直接舍弃该区间,这样下去,我们得到的$ans$值一定是越来越大的,然后可以舍弃的区间也就越来越多,从而比$O(n)$枚举每一个$a$和$b$更快,更加优秀。最终也可以得到最优解
实现基本上就是线段树+$DFS$:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 inline int read(){ 6 int sum(0); 7 char ch(getchar()); 8 for(;ch<‘0‘||ch>‘9‘;ch=getchar()); 9 for(;ch>=‘0‘&&ch<=‘9‘;sum=sum*10+(ch^48),ch=getchar());10 return sum;11 }12 typedef long long L;13 struct node{14 int l,r;15 L maxa,maxb;16 node *lch,*rch;17 node():l(0),r(0),maxa(0),maxb(0),lch(NULL),rch(NULL){}18 }a[400005],*root;19 int n,m,cnt;20 inline void pushup(node *rt){21 rt->maxa=max(rt->lch->maxa,rt->rch->maxa);22 rt->maxb=max(rt->lch->maxb,rt->rch->maxb);23 }24 inline void build(int l,int r,node *rt){25 rt->l=l,rt->r=r;26 if(l==r){27 rt->maxa=read(),rt->maxb=read();28 return;29 }30 rt->lch=&a[++cnt],rt->rch=&a[++cnt];31 int mid((l+r)>>1);32 build(l,mid,rt->lch);33 build(mid+1,r,rt->rch);34 pushup(rt);35 }36 inline L query_a(int l,int r,node *rt){37 if(l<=rt->l&&rt->r<=r)38 return rt->maxa;39 int mid((rt->l+rt->r)>>1);40 L ret(-0x7fffffff);41 if(l<=mid)42 ret=max(ret,query_a(l,r,rt->lch));43 if(mid<r)44 ret=max(ret,query_a(l,r,rt->rch));45 return ret;46 }47 inline L query_b(int l,int r,node *rt){48 if(l<=rt->l&&rt->r<=r)49 return rt->maxb;50 int mid((rt->l+rt->r)>>1);51 L ret(-0x7fffffff);52 if(l<=mid)53 ret=max(ret,query_b(l,r,rt->lch));54 if(mid<r)55 ret=max(ret,query_b(l,r,rt->rch));56 return ret;57 }58 L ans;59 inline void dfs(L x,L y,node *rt){60 if(rt->l==rt->r){61 ans=max(ans,x*(rt->maxa)+y*(rt->maxb));62 return;63 }64 L ans1(x*(rt->lch->maxa)+y*(rt->lch->maxb)),ans2(x*(rt->rch->maxa)+y*(rt->rch->maxb));65 if(ans1>ans)66 dfs(x,y,rt->lch);67 if(ans2>ans)68 dfs(x,y,rt->rch);69 }70 int main(){71 n=read(),m=read();72 root=&a[++cnt];73 build(1,n,root);74 for(int i=1;i<=m;++i){75 L x(read()),y(read());76 ans=-0x7fffffff;77 dfs(x,y,root);78 printf("%lld\n",ans);79 }80 }
[HZOJ10420]计算
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。