建議憑橙,思路橙,碼量紅到橙。
題面。
思路
一,暴力
直接依照題意模擬,複雜度 \(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;
}