杂题集萃[1]
Posted sparks-pion
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了杂题集萃[1]相关的知识,希望对你有一定的参考价值。
题意
给出 $N$ 个形如 $f_i(x)=a_ix^2+b_i$ 的二次函数。
有 $Q$ 次询问,每次给出一个 $x$,询问 $max(f_i(x))$。
输入格式
第一行两个整数 $N$,$Q$。
接下来的 $N$ 行,每行两个整数 $a_i$,$b_i$。
接下来的 $Q$ 行,每行一个整数 $x$。
输出格式
对于每个询问,输出一行一个整数表示答案。
input
2 4
3 0
4 -2
-1
0
1
2
output
6
0
3
12
限制与约定
每个测试点 $10$ 分,共 $10$ 个测试点:
对于所有的数据,有:
$1≤N,Q,|x_i|,|a_i|,|b_i|<32323$。
时间限制:1s
================================
题解
这道题看似是数据结构,但可以离线处理。
我们只要排一遍序维护一个凸壳就行了。
当$x<0$时将 $b_i$乘上$-1$就行了。QAQ
==================================
code
#include <bits/stdc++.h>
#define int long long
#define re register int
using namespace std;
inline void read(int &x){
x=0;char ch=getchar();bool f=0;
for(;!isdigit(ch);ch=getchar())f|=(ch=='-');
for(;isdigit(ch);ch=getchar())x=(x<<1)+(x<<3)+(ch^48);
x=f?-x:x;
}
const int N=5e5+10,M=32323;
int t,k[N],b[N],id[N],n,q,p[N],a1[M+1],a2[M+1];
inline int f(int x,int i){return k[x]*i*i+b[x]*i;}
inline int cmp(int x,int y){return (k[x]==k[y])?b[x]<b[y]:k[x]<k[y];}
inline double check(int i,int j){return 1.0*(b[j]-b[i])/(k[i]-k[j]);}
signed main(){
read(n),read(q);
for(re i=1;i<=n;++i) read(k[i]),read(b[i]),id[i]=i;
sort(id+1,id+n+1,cmp);t=0;
for(re i=1;i<=n;++i){
while(t&&k[id[i]]==k[p[t]]) --t;
while(t>1&&check(id[i],p[t])<=check(p[t],p[t-1])) --t;
p[++t]=id[i];
}
for(re i=1,j=1;i<=M;++i){
while(j<t&&f(p[j],i)<=f(p[j+1],i)) ++j;
a1[i]=f(p[j],i);
}
for(re i=1;i<=n;++i) b[i]=-b[i],p[i]=0;
sort(id+1,id+n+1,cmp);t=0;
for(re i=1;i<=n;++i){
while(t&&k[id[i]]==k[p[t]]) --t;
while(t>1&&check(id[i],p[t])<=check(p[t],p[t-1])) --t;
p[++t]=id[i];
}
for(re i=1,j=1;i<=M;++i){
while(j<t&&f(p[j],i)<=f(p[j+1],i)) ++j;
a2[i]=f(p[j],i);
}
while(q--){
int x;read(x);
if(x>0)printf("%lld
",a1[x]);
if(x==0) puts("0");
if(x<0)printf("%lld
",a2[-x]);
}
return 0;
}
以上是关于杂题集萃[1]的主要内容,如果未能解决你的问题,请参考以下文章