【Codeforces 1114F】Please, another Queries on Array?

Codeforces 1114 F

题意:给你一个序列\(a_{1\dots n}\),以及\(q\)次查询,每次查询有两种格式:

  • TOTIENT \(l\) \(r\):求出\(\phi(\Pi_{i=l}^ra_i)\)
  • MULTIPLY \(l\) \(r\) \(x\):将从\(l\)\(r\)的所有数乘上\(x\leq 300\)

处理每次查询。

思路:首先我们知道设\(x=\Pi_{i=1}^np_i^{e_i}\),则\(\phi(x)=x\Pi_{i=1}^n\frac{p_i-1}{p_i}\)

所以就可以想到记录每一个数的质因子有哪些。

由于这个序列的每个数都很小(\(a_i\leq 300\)),所以在此范围内的质数也不多(\(62\)个),然后就可以用一个\(long\ long\)存下了。

然后考虑高效地处理区间乘。

可以用分块和线段树来解决。(我只写了分块)

将原序列分成几块,每一个块的大小是\(B\),然后对于每个块存储以下信息:

  • 这个块所有数的积以及该乘积所含质因数
  • 这个块对于所有数同时乘的数以及这个数所含质因数
  • 这个块中每个数的值(这个只在边角的修改上要存)以及这个数所含质因数

每个操作的具体处理:

  • 修改:首先要改区间两边未在整块内的边角的每个数的值和整块的积,然后再将中间块的整块的同时乘的数都改为需要更改的数。
  • 查询:也是一样,现将区间两边的数乘上整块都要乘的数乘到答案里,再将中间块整块的乘积乘进答案。

然后就会发现如果要更改整块的积时需要求一个数的\(B\)次幂,那么就预处理一下即可。

然后具体的实现中还要注意一下一点点细节。

猜你喜欢

转载自www.cnblogs.com/denverjin/p/10468399.html