G - Pot!!

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;
}


猜你喜欢

转载自blog.csdn.net/qq_45772483/article/details/112850640
G