CF1891B Deja Vu 题解

建议凭橙,思路橙,码量红到橙。

题面

思路

一,暴力

直接依照题意模拟,复杂度 \(O(tqn^2)\),看一眼数据范围,妥妥 T 飞,倒在第三个点。

二,逐步优化

看一眼数据发现,虽然 \(q\) 很大,但实际上 \(x\) 只有三十个值,因此首先预处理出从 \(2^1\)\(2^{30}\) 的所有值,摘掉一个 \(n\),复杂度 \(O(tqn)\)

接下来不管怎样,即使把复杂度优化到 \(O(tq)\),复杂度依旧非常的高。\(t\) 组数据是不可能去掉的,因此考虑去掉 \(q\)。使复杂度变为 \(O(tn)\) 或者 \(O(tn)\) 的近似值。

考虑到对于每一个 \(a_i\),当它满足某一个 \(a_i \bmod 2^x=0\) 时。则 \((a_i+2^{x-1}) \bmod 2^x\) 此时一定不为 \(0\)。说人话就是当一个数被 \(2^x\) 整除过后,它就不会再能够整除这个 \(2^x\)

简单证明一下,当 \(a_i \bmod 2^x=0\) 时,对于 \((a_i+2^{x-1}) \bmod 2^x\),等价于 \(a_i \bmod 2^x+2^{x-1} \bmod 2^x\)。很明显 \(a_i \bmod 2^x=0\)\(2^{x-1} \bmod 2^x \ne 0\) 恒成立。即使在经过多个不同的 \(2^x\) 的处理后,这个结论依旧成立。

所以在 \(\text{AC}\) 代码中,对于每组数据,用一个数组 \(\text{book}\) 记录 \(x\) 是否出现过,复杂度 \(O(tn)\)

代码

#include<bits/stdc++.h>
#define ll long long
#define fr(i , a , b) for(ll i = a ; i <= b ; ++i)
#define fo(i , a , b) for(ll i = a ; i >= b ; --i)
using namespace std;
ll t , n , a[100005] , q , x;
ll qp[31] = {1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 , 256 , 512 , 1024 , 2048 , 4096 , 8192 , 16384 , 32768 , 65536 , 131072 , 262144 , 524288 , 1048576 , 2097152 , 4194304 , 8388608 , 16777216 , 33554432 , 67108864 , 134217728 , 268435456 , 536870912 , 1073741824};
ll book[31];
//priority_queue<ll> q;
//priority_queue <ll , vector<ll> , greater<ll> > q;
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> t;
	while(t--)
	{
		cin >> n >> q;
		fr(i , 1 , n)
		{
			cin >> a[i];
		}
		while(q--)
		{
			cin >> x;
			if(book[x])
			{
				continue;
			}
			book[x] = 1;
			fr(i , 1 , n)
			{
				if(a[i] % qp[x] == 0)
				{
					a[i] += qp[x - 1];
				}
			}
		}
		memset(book , 0 , sizeof(book));
		fr(i , 1 , n)
		{
			cout << a[i] << ' ';
		}
		cout << '\n';
	}
 	return 0;
}
posted @ 2024-04-10 17:36  心海秋的墨木仄  阅读(9)  评论(0编辑  收藏  举报