[题解] Codeforces Round #694 (Div. 2) B题 解题报告

B题

给定一个原始数组(a),长度为(n),再给定一个整数(x)

可以创建一个队列(q),将原始数组放到该队列,遍历队列。

如果当前元素 (q[head]) 能整除以(x),则将(x)(q[head] / x) 的结果放入到队列尾,当q[head]不能整除以(x),则停止操作,计算当前队列的元素总和。

所求输出即为当前队列的元素总和。

简单模拟了一下数据可以发现,

第一组数据可以派生出第二组数据,第二组数据可以派生出第三组数据

而派生后的总数量也是与组数和(x)有一定关系的,如:

第一组的一个数据派生到第二组,个数变为了x个

再次派生到第三组,数量变到了(x * x)
(...)
即第n组的数量为为 (x^{(n-1)})

所以在往队列添加元素的时候只需要添加一个数据,同时将答案自加(x^{(i-1)}*head[i])即可,大大降低了对空间的需求

代码如下:

#include <iostream>
#include <cmath>
#include <queue>

using namespace std;

typedef long long ll;
typedef pair<int, int> PII;  // 当前的数,第几组数据

const int N = 1e5 + 10;

ll solve ( void )
{
	bool st = false;
	ll sum = 0;
	queue<PII> q;

	int n, x;
	cin >> n >> x;

	for ( int i = 0; i < n; i++ )
	{
		int u;
		scanf ( "%d", &u );
		q.push ( {u, 0} );
	}

	while ( !q.empty() )
	{
		PII t = q.front();
		int a = t.first, r = t.second;
		
		q.pop();
		sum += a * pow ( x, r );

//              如果进入了if语句则说明达到终止条件,无需向队列尾添加元素了,只需要计算出队列中剩余项的总和即可
		if ( st || a % x != 0 )
		{
			st = true;
			continue;
		}

		q.push ( {a / x, r + 1} );
	}

	return sum;
}

int main ( void )
{
	int T;
	cin >> T;

	while ( T-- ) cout << solve() << endl;

	return 0;
}
作者:Jude_Zhang
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用BY-NC-SA 许可协议。转载请注明出处!
支持博主:如果您觉得文章对您有帮助,可以点击文章下方赞一下。您的鼓励是博主的最大动力!
原文地址:https://www.cnblogs.com/judezhang/p/14558817.html