Educational Codeforces Round 42 D. Merge Equals

Merge Equals

time limit per test: 2 second
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 x x x that occurs in the array 2 2 2 or more times. Take the first two occurrences of x x x 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 ⋅ x 2 \cdot x 2x).

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] [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]~\rightarrow~[3, 4, 2, 2, 2, 1]~\rightarrow~[3, 4, 4, 2, 1]~\rightarrow~[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] [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]~\rightarrow~[2, 3, 1, 1]~\rightarrow~[2, 3, 2]~\rightarrow~[3, 4] [1,1,3,1,1]  [2,3,1,1]  [2,3,2]  [3,4].

Input

The first line contains a single integer n n n ( 2 ≤ n ≤ 150   000 2 \le n \le 150\,000 2n150000) — the number of elements in the array.

The second line contains a sequence from n n n elements a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,,an ( 1 ≤ a i ≤ 1 0 9 1 \le a_i \le 10^{9} 1ai109) — the elements of the array.

Output

In the first line print an integer k k k — the number of elements in the array after all the performed operations. In the second line print k k k integers — the elements of the array after all the performed operations.

Example

i n p u t \tt input input
7
3 4 1 2 2 1 1
o u t p u t \tt output output
4
3 8 2 1
i n p u t \tt input input
5
1 1 3 1 1
o u t p u t \tt output output
2
3 4
i n p u t \tt input input
5
10 40 20 50 30
o u t p u t \tt output output
5
10 40 20 50 30

Tutorial

本题就是一个模拟题,但在模拟时需要考虑怎样删除元素

根据题意,相当于两个相同的元素,其中左侧的元素将合并到右侧的那个元素上,等价于左侧的元素变为 0 0 0,右侧的元素变成自己的两倍,所以只需要遍历数组,如果之前出现过相同的数,就将之前出现过的位置置为 0,自己就变为原来的 2 2 2 倍,直至不能再合并,最后数组中不为 0 的数就是答案

此解法时间复杂度为 O ( n ) \mathcal O(n) O(n)

Solution

#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long

signed main() {
    int n;
    cin >> n;
    map<int, int> idx;
    vector<int> a(n + 1), ans;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
        if (idx[a[i]]) {
            while (idx[a[i]]) {
                a[idx[a[i]]] = 0;
                idx.erase(a[i]);
                a[i] <<= 1;
            }
            idx[a[i]] = i;
        } else {
            idx[a[i]] = i;
        }
    }
    for (int ai : a) {
        if (ai) {
            ans.emplace_back(ai);
        }
    }
    cout << ans.size() << endl;
    for (int ai : ans) {
        cout << ai << " \n"[ai == ans.back()];
    }
    return 0;
}

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"educational codeforces round 103 (rated for div. 2)"是一个Codeforces平台上的教育性比赛,专为2级选手设计评级。以下是有关该比赛的回答。 "educational codeforces round 103 (rated for div. 2)"是一场Codeforces平台上的教育性比赛。Codeforces是一个为程序员提供竞赛和评级的在线平台。这场比赛是专为2级选手设计的,这意味着它适合那些在算法数据结构方面已经积累了一定经验的选手参与。 与其他Codeforces比赛一样,这场比赛将由多个问题组成,选手需要根据给定的问题描述和测试用例,编写程序来解决这些问题。比赛的时限通常有两到三个小时,选手需要在规定的时间内提交他们的解答。他们的程序将在Codeforces的在线评测系统上运行,并根据程序的正确性和效率进行评分。 该比赛被称为"educational",意味着比赛的目的是教育性的,而不是针对专业的竞争性。这种教育性比赛为选手提供了一个学习和提高他们编程技能的机会。即使选手没有在比赛中获得很高的排名,他们也可以从其他选手的解决方案中学习,并通过参与讨论获得更多的知识。 参加"educational codeforces round 103 (rated for div. 2)"对于2级选手来说是很有意义的。他们可以通过解决难度适中的问题来测试和巩固他们的算法和编程技巧。另外,这种比赛对于提高解决问题能力,锻炼思维和提高团队合作能力也是非常有帮助的。 总的来说,"educational codeforces round 103 (rated for div. 2)"是一场为2级选手设计的教育性比赛,旨在提高他们的编程技能和算法能力。参与这样的比赛可以为选手提供学习和进步的机会,同时也促进了编程社区的交流与合作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值