标签:分数 le pop queue 灵动 y1 x1 0707 集训
团结力量大
Description
为了让大家体会团结力量大,高老师决定带领大家做一个活动,她把同学们分成了 n 个小组,每组 m 个同学,每个同学手里有一个自然数。
她让每组内的同学按如下方式合并成团:
- 初始时每人是一个团,每人手里的数字为该团的分数
- 每次可以将两个团合并成为一个新团,分数为原来两个团的分数乘积+1,例如:两个分数分别为 3 和 5 的团,合并后的新团分数为 \(3\times 5 + 1 = 16\)。
- 每组同学按上述方式合并,直至整个组合并为一个团
高老师的学生都非常聪明,现在她想知道,每个组最高合并出的分数是多少?答案保证在 \(2^{63}-1\) 以内。
Format
Input
第一行输入两个整数 \(n,m(1\le n\le 500000, 1\le m \le 20)\)
第二行开始,每行输入 \(m\) 个整数,表示一个组中每位同学的分数\((0\sim 7)\)
Output
共 n 行,每行一个整数,表示对应的组可以合并出的最高分。
Editorial
this problem seems like "合并果子" in which it can be proved that choosing the smallest value always gives the maximum answer.
Actually,this problem has the same editorial with it : always select the smallest.
Using priority queue it's quite a well solution,but in this question,Time complexity should to be close to \(O(n)\).therefore,we can use bucket sort to replace std::sort,and optimizing priority queue with normal queues.
we assume that queue q has all the result of the merge. obviously,the elements in q are monotonically increasing. therefore,the smallest elements is between the sorted array \(a\) and the front of the queue \(q\).
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
queue<ll>x,y;
//get the minimum between two queues
ll Get() {
int x1 = -1;
if(x.size())
x1 = x.front();
int y1 = -1;
if(y.size())
y1 = y.front();
if(x1==-1) {
y.pop();
return y1;
}
if(y1==-1) {
x.pop();
return x1;
}
if(x1<y1) {
x.pop();
return x1;
} else {
y.pop();
return y1;
}
}
int main() {
int n,m;
cin >> n >> m;
while(n--) {
// clear
while(x.size())
x.pop();
while(y .size())
y.pop();
vector<ll>a(m);
for(auto &i:a)
cin >> i;
if(m==1) {
cout << a[0] << endl;
return 0;
}
sort(a.begin(),a.end());
for(auto &i:a)
x.push(i);
while(x.size()!=0||y.size()!=1) {
ll n1 = Get(), n2 = Get();
y.push(n1*n2+1);
}
cout << y.front() << endl;
}
}
标签:分数,le,pop,queue,灵动,y1,x1,0707,集训 来源: https://www.cnblogs.com/zhaohanzheng/p/16457523.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。