D. Merge Equals
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given an array of positive integers. While there are at least two equal elements, we will perform the following operation. We choose the smallest value xx that occurs in the array 22 or more times. Take the first two occurrences of xx in this array (the two leftmost occurrences). Remove the left of these two occurrences, and the right one is replaced by the sum of this two values (that is, 2⋅x2⋅x).
Determine how the array will look after described operations are performed.
For example, consider the given array looks like [3,4,1,2,2,1,1][3,4,1,2,2,1,1]. It will be changed in the following way: [3,4,1,2,2,1,1] → [3,4,2,2,2,1] → [3,4,4,2,1] → [3,8,2,1][3,4,1,2,2,1,1] → [3,4,2,2,2,1] → [3,4,4,2,1] → [3,8,2,1].
If the given array is look like [1,1,3,1,1][1,1,3,1,1] it will be changed in the following way: [1,1,3,1,1] → [2,3,1,1] → [2,3,2] → [3,4][1,1,3,1,1] → [2,3,1,1] → [2,3,2] → [3,4].
Input
The first line contains a single integer nn (2≤n≤1500002≤n≤150000) — the number of elements in the array.
The second line contains a sequence from nn elements a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109) — the elements of the array.
Output
In the first line print an integer kk — the number of elements in the array after all the performed operations. In the second line print kk integers — the elements of the array after all the performed operations.
Examples
input
Copy
7
3 4 1 2 2 1 1
output
Copy
4
3 8 2 1
input
Copy
5
1 1 3 1 1
output
Copy
2
3 4
input
Copy
5
10 40 20 50 30
output
Copy
5
10 40 20 50 30
Note
The first two examples were considered in the statement.
In the third example all integers in the given array are distinct, so it will not change.
一、原题地址
二、大致题意
给出n个数,然后每次操作都会把数组中最小的两个数取出来,如果这两个数相同,则把左边那个从数组中删除,然后把右边那个置为这两个数的和。询问的是最后这个数组会变成什么样。
三、思路
STL水题
四、代码
#include <vector>
#include <iostream>
#include <string>
#include <map>
#include <stack>
#include <cstring>
#include <queue>
#include <list>
#include <cstdio>
#include <set>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <iomanip>
#include <cctype>
#include <sstream>
#include <iterator>
#include <functional>
#include <stdlib.h>
#include <time.h>
#include <bitset>
using namespace std;
#define LL long long
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
int n;
LL a[200000];
map<LL, set<int>>mmp;
void read()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%lld", &a[i]);
mmp[a[i]].insert(i); //读入并且记录a[i]这个数所在的位置
}
}
void solve()
{
map<LL, set<int>>::iterator it = mmp.begin(); //map保证每次取出的数是最小的
for (; it != mmp.end(); it++)
{
while (it->second.size() >= 2) //若这个数的位置有两个
{
set<int>::iterator iit = it->second.begin(),t;
t = iit; t++;
a[*iit] = -inf; //将第一个数位置处的数置为-inf
a[*t] = 2 * it->first; //将第二个数的位置处的数据翻倍
mmp[2 * it->first].insert(*t); //新加入的数也要记录位置
it->second.erase(iit);
it->second.erase(t); //删除这两个数的位置
}
}
int ans = 0;
for (int i = 1; i <= n; i++)
{
if (a[i] != -inf)ans++;
}
printf("%d\n", ans);
for (int i = 1; i <= n; i++)
{
if (a[i] != -inf)printf("%lld ",a[i]);
}
}
void work()
{
read();
solve();
}
int main()
{
work();
getchar();
getchar();
}