1. 程式人生 > >Newcoder 83 C.吉姆的奇思妙想(貪心)

Newcoder 83 C.吉姆的奇思妙想(貪心)

Description

給你兩個正整數M,nM, n, 以及兩個長度為nn個正整數序列deg1,deg2,...,degndeg_1,deg_2,..., deg_nfreq1,freq2,...,freqnfreq_1, freq_2,..., freq_n

你要回答qq個問題,第ii個問題會給你22個正整數ai,bia_i, b_i,請找到一個整數ss使得以下式子(Ei)(E_i) 的值最小:
Ei=ai×1jn,degjsdegj2freqj+

bi×1jn,degj>sMfreqj E_i=a_i\times \sum\limits_{1\le j\le n,deg_j\le s}deg_j^2\cdot freq_j+b_i\times \sum\limits_{1\le j\le n,deg_j>s}M\cdot freq_j
Input

輸入共有1+n+1+q1+n+1+q行。

第一行有兩個正整數M,nM,n

接下來的nn 行中的第i

i行有兩個正整數degideg_ifreqifreq_i

下一行有一個正整數qq

最後 qq 行中的第 $i $行有兩個正整數 ai,bia_i, b_i

(1M,degi,freqi1010,1n2105,1q5104,1ai,bi2103,degi<degi+1)(1\le M,deg_i,freq_i\le 10^{10},1\le n\le 2\cdot 10^5,1\le q\le 5\cdot 10^4,1\le a_i,b_i\le 2\cdot 10^3,deg_i<deg_{i+1})

egi,freqi1010,1n2105,1q5104,1ai,bi2103,degi<degi+1)

Output

對於每個詢問都輸出一行包含一個整數,代表式子EiE_i的最小值。

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

degdeg的單調性有min(Ei)=1jnmin(aidegj,biM)freqjmin(E_i)=\sum\limits_{1\le j\le n}min(a_i\cdot deg_j,b_i\cdot M)\cdot freq_j

故取ss為滿足aidegsbiMa_i\cdot deg_s\le b_i\cdot M的最大值即可,也即s=biMais=\lfloor\sqrt{\frac{b_i\cdot M}{a_i}}\rfloor

此時有min(Ei)=ai1jsdegj2freqj+biMs&lt;jnfreqjmin(E_i)=a_i\cdot\sum\limits_{1\le j\le s}deg_j^2\cdot freq_j+b_i\cdot M\cdot \sum\limits_{s&lt;j\le n}freq_j,維護一下degj2freqjdeg_j^2\cdot freq_j的字首和以及freqjfreq_j的字尾和即可在知道ssO(1)O(1)查詢

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