目录
题目:
给两个数组,和数m。
如果两个数组中的一个数可以除尽m , 那就可以把这个数拆成m个相同的数。
如果连续m个数相同,就可以合并成一个m倍的它。
思路:
正难则反,我们把两个数组都尽可能地拆,最后看两个数组是否相同。相同的数站一个位置,另外开辟空间记录有多少个即可。
参考代码:
#define ll long long
#define endl "\n"
#define int long long
const ll inf = 1e9;
const ll MOD = 0x77777777737;
const int maxn = 5e5 + 5;
void solve()
{
int n,m;
cin >> n >> m;
vector<int>arr1(n);
for (int i = 0; i < n; i++)
cin >> arr1[i];
int k;
cin >> k;
vector<int>arr2(k);
for (int i = 0; i < k; i++)
cin >> arr2[i];
vector<pair<int, int>>a1(max(n, k)), a2(max(n, k));
int cur = 0;
for (int i = 0; i < n; i++)
{
if (arr1[i] % m == 0)
{
int aim = arr1[i]/m ,num = m;
while (aim % m == 0)
{
num *= m;
aim /= m;
}
if (cur > 0 && aim == a1[cur - 1].first)
{
a1[cur - 1].second += num;
}
else
{
a1[cur].first = aim;
a1[cur].second = num;
cur++;
}
}
else
{
if (cur > 0 && arr1[i] == a1[cur - 1].first)
{
a1[cur - 1].second++;
}
else
{
a1[cur].first = arr1[i];
a1[cur].second = 1;
cur++;
}
}
}
cur = 0;
for (int i = 0; i < k; i++)
{
if (arr2[i] % m == 0)
{
int aim = arr2[i] / m, num = m;
while (aim % m == 0)
{
num *= m;
aim /= m;
}
if (cur > 0 && aim == a2[cur - 1].first)
{
a2[cur - 1].second+= num;
}
else
{
a2[cur].first = aim;
a2[cur].second = num;
cur++;
}
}
else
{
if (cur > 0 && arr2[i] == a2[cur - 1].first)
{
a2[cur - 1].second++;
}
else
{
a2[cur].first = arr2[i];
a2[cur].second = 1;
cur++;
}
}
}
for (int i = 0; i < max(n,k); i++)
{
if (a1[i] != a2[i])
{
cout << "No" << endl;
return;
}
}
cout << "Yes" << endl;
}
signed main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}