Official

D - Merge Slimes Editorial by en_translator


Let us define the type of a size-\(S\) slime as the maximum odd divisor of \(S\) (i.e. the number obtained by repeatedly dividing \(S\) by \(2\) while possible). Then, a synthesis of slimes preserves their slime type, and preserves the number of slimes with the other types, so the synthesis can be considered independently for each type.

The sizes of slimes of type \(d\) are \(d\), \(2d\), \(4d\), \(\ldots\), \(2^kd\), \(\ldots\). For \(k=0,1,2,\ldots\), suppose that there were \(A_k\) slimes of size \(2^kd\) (where \(A_k=0\) is possible). Here, define the value of a (multi)set of type-\(d\) slimes as \(A_0+2A_1+4A_2+\cdots 2^kA_k+\cdots\), which remains the same by a synthesis.

Here, let us consider the minimum number of slimes in a set of type-\(d\) slimes. Such set has at most one (type-\(d\)) slime of each size; otherwise, one can choose and synthesize two of them to reduce the number of slimes without changing the value. Moreover, such set is unique, because such a set corresponds one-by-one to an integer sequence \((A_0,A_1,\ldots,A_k,\ldots)\) consisting of \(0\) and \(1\) such that \(v=A_0+2A_1+4A_2+\cdots 2^kA_k+\cdots\), which is unique by the uniqueness of binary representation. Finally, this can be achieved by repeatedly applying synthesis on any set of slimes of value \(v\) because, as already described, if we repeat synthesis until no more operations can be done, we always end up in this set. Since the number of slimes decreases by one in each synthesis, it is also guaranteed that only finite number of operations is required.

Therefore, what we need to do is to, for each type for which one or more slimes exist, compute the value and count the number of standing bits in the binary representation of the value. By managing the value for each type in an map, one can find the value of each type in a total of \(O(N(\log N+\log \max(S_i)))\) time and the minimum number of slimes for each type in a total of \(O(N(\log\max(S_i)+\log \max(C_i) ))\) time. Therefore, the total complexity is \(O(N(\log N+\log \max(S_i)+\log \max(C_i)))\).

Supplement

As a consequence of the description above, given a (multi)set of slimes, the final set where no more actions can be performed is unique, independent of the order of actions, where the number of slimes end up being minimum. A synthesis of slimes of sizes \(x\) or greater does not produce a slime of size \(x\) or less, so one can simulate the process of synthesis from the smaller to the larger, in order to find the answer. With an appropriate data structure like ordered set or ordered queue, one can find the answer in a total of \(O(N(\log \max(S_i)+\log \max(C_i))\log(N(\log \max(S_i)+\log \max(C_i)))\) time. While the complexity is a bit worse than the approach above, you can still get AC (accepted) as long as the constant factor is not that large.

Sample code in C++:

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

int main(void) {
	int n,x,ans=0;
	long long y;
	map<int,long long>mp;
	map<int,long long>::iterator itr;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>x>>y;
		while((x&1)==0){
			x>>=1,y<<=1;
		}
		mp[x]+=y;
	}
	itr=mp.begin();
	while(itr!=mp.end()){
		y=(*itr).second;
		while(y>0){
			if(y&1)ans++;
			y>>=1;
		}
		itr++;
	}
	cout<<ans<<endl;
	return 0;
}

Sample code in C++ (approach mentioned in supplement):

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

int main(void) {
	int n,ans=0;
	long long x,y;
	map<long long,long long>mp;
	map<long long,long long>::iterator itr;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>x>>y;
		mp[x]+=y;
	}
	itr=mp.begin();
	while(itr!=mp.end()){
	  x=(*itr).first, y=(*itr).second;
		if(y>1)mp[2*x]+=(y/2);
		if(y&1)ans++;
		itr++;
	}
	cout<<ans<<endl;
	return 0;
}

posted:
last update: