The 13th Chinese Northeast Contest B. Balanced Diet(前缀和)
Posted li_wen_zhuo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了The 13th Chinese Northeast Contest B. Balanced Diet(前缀和)相关的知识,希望对你有一定的参考价值。
题目描述
Taylor is wandering in a milk candy store. The store has m types of sweets and there are n sweets in the store. The i-th sweet has the value of ai, and it is of type bi.
Taylor is planning to buy some sweets in the store, each sweet can be bought at most once. He will buy at least one sweet. Taylor knows that a balanced diet is important, the value of a sweet set is measured as S/C, where S denotes the sum of ai and C denotes the maximum number of occurrences among all types of sweets.
Assume Taylor selects pi sweets of type i, it is not welcomed if 1≤pi<li. Note that pi can also be 0 and pi can be everything when li=1.
Please write a program to help Taylor find the sweet set with maximum value.
Input
The first line of the input contains an integer T(1≤T≤1000), denoting the number of test cases.
In each test case, there are two integers n,m(1≤n,m≤100000) in the first line, denoting the number of sweets and types.
In the second line, there are m integers l1,l2,…,lm(1≤li≤n).
For the next n lines, each line contains two integers ai,bi(1≤ai≤108,1≤bi≤m), denoting each sweet.
It is guaranteed that ∑n≤106 and ∑m≤106, and there always exists a valid sweet set.
Output
For each test case, print a single line of format u/v, denoting the maximum value uv. Note that you should guarantee that gcd(u,v)=1.
Example
Input
2
2 1
2
7 1
2 1
3 2
1 2
2 1
5 2
3 2
Output
9/2
5/1
题目大意
给出了n和m,表示有m种类型的糖果,这些糖果一共n个。
接下了是m个数,表示如果你选了第 i 种糖果,那么你最少选 Li (你也可以不选)
再接下来就是 n 行数据,每一行 a[i] 和 b[i] 表示这个糖果属于 bi 这个种类的,它的价值是a[i]。
最后让你输出你挑选的糖果的总价值除以 你取得糖果中数量最多的那种糖果的数量,然后化成最简分数。
题目分析
num[i] //表示第i种糖果最少选多少个
用邻接表st[b] //表示b类的糖果有哪些,并记录其价值
邻接表g[i] //表示选取糖果数量最多的那一种数量为i时,与i-1相比,多选择了哪一些糖果,并记录其价值
然后前缀和处理g[i],并记录最大的 s u m ( g [ 1 − i ] ) / i sum(g[1-i])/i sum(g[1−i])/i 即可。(思路不太好说,看代码吧)
代码如下
#include <iostream>
#include <cmath>
#include <cstdio>
#include <set>
#include <string>
#include <cstring>
#include <map>
#include <algorithm>
#include <stack>
#include <queue>
#include <bitset>
#define LL long long
#define ULL unsigned long long
#define PII pair<LL,LL>
#define PDD pair<double,double>
#define x first
#define y second
using namespace std;
const int N=1e5+5,INF=1e9+7;
int num[N];
vector<int> st[N],g[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
for(int i=0;i<N;i++) st[i].clear(),g[i].clear();
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) scanf("%d",&num[i]);
for(int i=1;i<=n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
st[b].push_back(a); //维护邻接表st[]
}
for(int i=1;i<=m;i++)
{
sort(st[i].begin(),st[i].end(),greater<int>()); //为了使获得的答案最大,应该让大的值往前排
for(int j=0;j<st[i].size();j++)
g[max(num[i],j+1)].push_back(st[i][j]); //如果要选第i种糖果,那么至少要选num[i]种因此g[]的下标要从num[i]开始
}
LL sum=0,ans=0,k=1; //sum记录前缀和,ans/k记录最大值
for(int i=1;i<=n;i++) //枚举最大数量i
{
for(int j=0;j<g[i].size();j++) //将g[i]中的数全部加入sum
sum+=g[i][j];
if(1.0*ans/k<1.0*sum/i) ans=sum,k=i;//记录最大值
}
LL gcd=__gcd(ans,k); //约分
printf("%lld/%lld\\n",ans/gcd,k/gcd);
}
return 0;
}
以上是关于The 13th Chinese Northeast Contest B. Balanced Diet(前缀和)的主要内容,如果未能解决你的问题,请参考以下文章
The 13th Chinese Northeast Contest C. Line-line Intersection(平面几何)
The 13th Chinese Northeast Collegiate Programming Contest E题
The 15th Chinese Northeast Collegiate H - Loneliness(思维,构造)
The 15th Chinese Northeast Collegiate H - Loneliness(思维,构造)
The 15th Chinese Northeast Collegiate C. Vertex Deletion(树形dp)
The 15th Chinese Northeast L. k-th Smallest Common Substring(广义SAM,对节点字典序排序)