Description
Little Q is very sleepy, and he really needs some coffee to make him awake. At this time, Little L brings a pot to Little Q, and he states the pot as follows.
For a prime number p, if p^m | n and p^{m+1}\not | n, we say \text{pot}_p(n)=m.
The pot is very special that it can make everyone awake immediately.
Now Little L provides (1 \le n \le 10^5) integers a_1, a_2, \cdots, a_n to Little Q, each of which is 1 initially. After that, Little L shows 2 types of queries:
MULTIPLY l r x : For every i∈[l,r] (1≤l≤r≤n), multiply a_i by x (2 \le x \le 10).
MAX l r : Calculate the value of
\displaystyle \max_{l\le i\le r} \left{ \max_{p|a_i} \left{ \text{pot}_p (a_i) \right} \right}~(1 \le l \le r \le n),
where p is prime.
Now you need to perform q(1 \le q \le 10^5) queries of these two types of queries described above.
If you perform a “MULTIPLY” query, you don’t need to output anything.
If you perform a “MAX” query, you need to output a line like ANSWER y, where y the value you’ve calculated.
Input
The first line contains two integers n(1 \le n \le 10^5) and q(1 \le q \le 10^5), the number of integers and the number of queries.
Each of the next q lines contains one type of query described above.
Output
For each “MAX” query, output one line in the format of ANSWER y, where y the value you have calculated.
样例输入
5 6
MULTIPLY 3 5 2
MULTIPLY 2 5 3
MAX 1 5
MULTIPLY 1 4 2
MULTIPLY 2 5 5
MAX 3 5
样例输出
ANSWER 1
ANSWER 2
样例解释
If m and n are non-zero integers, or more generally, non-zero elements of an integral domain, it is said that m divides n if there exists an integer k, or an element k of the integral domain, such that m \times k=n, and this is written as m \mid n.
题目大意:
给定初始值为1的n个数,执行以下两种操作:
1、将 [l,r] 区间内的整数都乘以x
2、询问 [l,r] 区间内的一个极值,即
\displaystyle \max_{l\le i\le r} \left{ \max_{p|a_i} \left{ \text{pot}_p (a_i) \right} \right}~(1 \le l \le r \le n)
求一个区间内最大的那个值,我们通过细致的观察题目,发现要乘的那个数的范围很小,一个数的那个函数的值是多少,即问那个数的哪个质因子的次数最高,即问哪个质因子在对哪个数乘的次数最多,因为是区间修改i,所以用到懒标记,从上到下,维护的是一段区间哪个数的因子的次数最多
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
struct Segment_tree
{
int l, r;
int maxd2, maxd3, maxd5, maxd7;
int add2, add3, add5, add7;
int maxd;
} tr[N * 4];
int n, m;
void pushup(Segment_tree &u, Segment_tree &l, Segment_tree &r)
{
u.maxd2 = max(l.maxd2, r.maxd2);
u.maxd3 = max(l.maxd3, r.maxd3);
u.maxd5 = max(l.maxd5, r.maxd5);
u.maxd7 = max(l.maxd7, r.maxd7);
u.maxd = max(max(u.maxd2, u.maxd3), max(u.maxd5, u.maxd7));
}
void pushup(int u)
{
pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}
void pushdown(int u)
{
if (tr[u].add2){
tr[u << 1].add2 += tr[u].add2;
tr[u << 1 | 1].add2 += tr[u].add2;
tr[u << 1].maxd2 += tr[u].add2;
tr[u << 1 | 1].maxd2 += tr[u].add2;
}
if (tr[u].add3){
tr[u << 1].add3 += tr[u].add3;
tr[u << 1 | 1].add3 += tr[u].add3;
tr[u << 1].maxd3 += tr[u].add3;
tr[u << 1 | 1].maxd3 += tr[u].add3;
}
if (tr[u].add5){
tr[u << 1].add5 += tr[u].add5;
tr[u << 1 | 1].add5 += tr[u].add5;
tr[u << 1].maxd5 += tr[u].add5;
tr[u << 1 | 1].maxd5 += tr[u].add5;
}
if (tr[u].add7){
tr[u << 1].add7 += tr[u].add7;
tr[u << 1 | 1].add7 += tr[u].add7;
tr[u << 1].maxd7 += tr[u].add7;
tr[u << 1 | 1].maxd7 += tr[u].add7;
}
tr[u << 1].maxd = max(max(tr[u << 1].maxd2, tr[u << 1].maxd3), max(tr[u << 1].maxd5, tr[u << 1].maxd7));
tr[u << 1 | 1].maxd = max(max(tr[u << 1 | 1].maxd2, tr[u << 1 | 1].maxd3), max(tr[u << 1 | 1].maxd5, tr[u << 1 | 1].maxd7));
tr[u].add2 = tr[u].add3 = tr[u].add5 = tr[u].add7 = 0;
}
void build(int u, int l, int r)
{
if (l != r) tr[u] = {
l, r};
else
{
tr[u] = {
l, r, 0, 0, 0, 0, 0, 0, 0, 0, 0};
return;
}
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void modify(int u, int l, int r, int d2, int d3, int d5, int d7)
{
if (tr[u].l >= l && tr[u].r <= r)
{
tr[u].maxd2 += d2;
tr[u].maxd3 += d3;
tr[u].maxd5 += d5;
tr[u].maxd7 += d7;
tr[u].add2 += d2;
tr[u].add3 += d3;
tr[u].add5 += d5;
tr[u].add7 += d7;
tr[u].maxd = max(max(tr[u].maxd2, tr[u].maxd3), max(tr[u].maxd5, tr[u].maxd7));
return ;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) modify(u << 1, l, r, d2, d3, d5, d7);
if (r > mid) modify(u << 1 | 1, l, r, d2, d3,d5, d7);
pushup(u);
}
Segment_tree query(int u, int l, int r)
{
if (tr[u].l >= l && tr[u].r <= r) return tr[u];
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (r <= mid) return query(u << 1, l, r);
if (l > mid) return query(u << 1 | 1, l, r);
Segment_tree total, l_tree, r_tree;
l_tree = query(u << 1, l, r);
r_tree = query(u << 1 | 1, l, r);
pushup(total, l_tree, r_tree);
return total;
}
int main()
{
scanf("%d%d", &n, &m);
build(1, 1, n);
char s[10];
//cout << "------" << endl;
while(m --){
scanf("%s", s);
if (s[1] == 'U'){
int l, r, x;
scanf("%d%d%d", &l, &r, &x);
int x2 = 0, x5 = 0, x7 = 0, x3 = 0;
if (x == 2) x2 ++;
else if (x == 3) x3 ++;
else if (x == 4) x2 += 2;
else if (x == 5) x5 ++;
else if (x == 6) x2 ++, x3 ++;
else if (x == 7) x7 ++;
else if (x == 8) x2 += 3;
else if (x == 9) x3 += 2;
else if (x == 10) x2 ++, x5 ++;
modify(1, l, r, x2, x3, x5, x7);
}
else{
int l, r;
scanf("%d%d", &l, &r);
cout << "ANSWER " << query(1, l, r).maxd << endl;
}
}
return 0;
}