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;
}
- 一个好的指挥官不会背叛他的军队,无论代价是什么。
- 一个更好的指挥官知道当他想背叛他的军队时,什么时候应该伪装。
- 一个最好的指挥官精明地确立自己的绝对领导,并引领着人民走向更好的未来。