Newcoder 83 C.吉姆的奇思妙想(貪心)
阿新 • • 發佈:2019-01-03
Description
給你兩個正整數, 以及兩個長度為個正整數序列 和。
你要回答個問題,第個問題會給你個正整數,請找到一個整數使得以下式子 的值最小:
Input
輸入共有行。
第一行有兩個正整數。
接下來的 行中的第行有兩個正整數和。
下一行有一個正整數。
最後 行中的第 $i $行有兩個正整數 。
Output
對於每個詢問都輸出一行包含一個整數,代表式子的最小值。
Sample Input
5 4
1 1
2 1
3 1
4 1
5
1 1
3 2
2000 1
1 2000
2000 2000
Sample Output
15
33
20
30
30000
Solution
由的單調性有
故取為滿足的最大值即可,也即
此時有,維護一下的字首和以及的字尾和即可在知道後查詢
Code
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>P;
const int maxn=200005;
#define fi first
#define se second
int n,q;
ll M,L[maxn],R[maxn];
P x[maxn];
int main()
{
scanf("%lld%d",&M,&n);
for(int i=1;i<=n;i++)scanf("%lld%lld",&x[i].fi,&x[i].se);
for(int i=1;i<=n;i++)L[i]=L[i-1]+x[i].fi*x[i].fi*x[i].se;
for(int i=n;i>=1;i--)R[i]=R[i+1]+x[i].se;
scanf("%d",&q);
while(q--)
{
int a,b;
scanf("%d%d",&a,&b);
ll c=(ll)sqrt(M*b/a+0.5);
int pos=upper_bound(x+1,x+n+1,P(c,1e11))-x-1;
printf("%lld\n",L[pos]*a+R[pos+1]*M*b);
}
return 0;
}