AtCoder Contest 238 - G 题解


AtCoder Contest 238 - G 题解

题目内容

Given a sequence AA of NN numbers, answer the following QQ questions.

  • In the ii-th question, you are given integers LiL_i and RiR_i . Is ALi×ALi+1×…×ARiA_{L_i} \times A_{L_i+1} \times \dots \times A_{R_i}A a cubic number?

Here, a positive integer xx is said to be a cubic number when there is a positive integer yy such that x=y3x=y^3 .

给定长为N的序列A,Q 组询问 (l,r),
判断 (∏i=lrAi\prod \limits_{i=l}^{r}A_i) 是否是完全立方数。
(1≤N,Q≤2×105,1≤Ai≤106)(1 \le N,~Q \le 2 \times 10^5,~1 \le A_i \le 10^6).

Hash做法

Code

  • 每个质因子生成三个不同的Hash, 满足 X2=X0⊕X1{X_2} = {X_0} \oplus {X_1} .
  • 逐个质因子更新异或和序列 HjH_j , Hj←Hj⊕Ximod⁡3{H_j} \leftarrow {H_j} \oplus {X_{i\bmod 3}} , 使每个质因子三个不同的Hash轮流出现。
  • 异或具有交换律和归零律,可得到: [l,r][l, r] 区间内每个质因子的个数都是 33 的倍数 ⇒ Hl⊕Hl+1⊕…⊕Hr=0H_l \oplus H_{l+1} \oplus \dots \oplus H_r = 0 .(注意,反向不成立)
  • 使用异或前缀和 H′H' 加快查询速度。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include<bits/stdc++.h>

#define MAX 1000005

using namespace std;

int main()
{
int n, q;
cin >> n >> q;
vector<int> a(n);
for (auto &nx: a)
{ cin >> nx; }
vector<int> l(q), r(q);
for (int i = 0; i < q; i++)
{ cin >> l[i] >> r[i]; }

uint_fast64_t seed = 202202052100238523;
mt19937_64 engine(seed);
vector<vector<int>> pf(MAX);
for (int i = 2; i < MAX; i++)
{
if (!pf[i].empty())
{ continue; }
for (int j = i; j < MAX; j += i)
{
int mj = j;
while (mj % i == 0)
{
pf[j].push_back(i);
mj /= i;
}
}
}
vector<bool> res(q, true);
for (int tr = 0; tr < 3; tr++)
{
vector<vector<uint_fast64_t>> hs(MAX, vector<uint_fast64_t>(3, 0));
for (int i = 0; i < MAX; i++)
{
while (hs[i][0] == 0)
{ hs[i][0] = engine(); }
while (hs[i][1] == 0 || hs[i][0] == hs[i][1])
{ hs[i][1] = engine(); }
hs[i][2] = (hs[i][0] ^ hs[i][1]);
}
vector<int> bk(MAX, 0);
vector<uint_fast64_t> rw(n + 1, 0);
for (int i = 0; i < n; i++)
{
rw[i + 1] = rw[i];
for (auto &nx: pf[a[i]])
{
rw[i + 1] ^= hs[nx][bk[nx] % 3];
bk[nx]++;
}
}
for (int i = 0; i < q; i++)
{
if (rw[l[i] - 1] != rw[r[i]])
{ res[i] = false; }
}
}
for (int i = 0; i < q; i++)
{
if (res[i])
{ cout << "Yes\n"; }
else
{ cout << "No\n"; }
}
return 0;
}

文章作者: sfc9982
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 sfc9982 !
  目录