不知道为什么感觉其他博客写的很复杂,有点看不懂…

用 m a p 记 录 每 个 数 值 出 现 的 上 一 次 下 标 用map记录每个数值出现的上一次下标 map

在 枚 举 到 a i 时 , 看 一 下 m a p 以 前 有 没 有 a i 这 个 值 , 没 有 就 把 下 标 存 进 去 在枚举到a_i时,看一下map以前有没有a_i这个值,没有就把下标存进去 ai,mapai,

有 的 话 就 取 出 以 前 的 那 个 下 标 , 抹 掉 , 自 己 翻 倍 , 然 后 重 复 这 个 过 程 有的话就取出以前的那个下标,抹掉,自己翻倍,然后重复这个过程 ,,,

可能你会疑惑,这里不是按照从小到大消除的,是一旦出现就消除,为什么对了呢?

因 为 这 两 个 相 同 的 数 在 最 左 边 , 迟 早 要 消 掉 因为这两个相同的数在最左边,迟早要消掉 ,

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=2e5+10;
int n,a[maxn],s;
map<int,int>m;
signed main()
{
	cin >> n;
	int s=n;
	for(int i=1;i<=n;i++)
	{
		cin >> a[i];
		if( m[ a[i] ] )
		{
			while( m[ a[i] ])
			{
				int index = m[ a[i] ];
				a[index]=0,s--,m[ a[i] ] =0;//清空
				a[i] = 2*a[i];
			}
			m[ a[i] ]=i;
		}	
		else	m[ a[i] ]=i;
	}
	cout<<s<<endl;
	for(int i=1;i<=n;i++)
		if( a[i] )	cout<<a[i]<<" ";
}