首页 > 其他 > 详细

2019 ICPC Asia Yinchuan Regional G. Pot!!(线段树/数论)

时间:2021-05-08 23:20:01      阅读:19      评论:0      收藏:0      [点我收藏+]

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 pp, if p^m | np**mn and p^{m+1}\not | np**m+1\∣n, we say \text{pot}_p(n)=mpotp(n)=m.

The pot is very special that it can make everyone awake immediately.

Now Little L provides n~(1 \le n \le 10^5)n (1≤n≤105) integers a_1, a_2, \cdots, a_na1,a2,?,a**n to Little Q, each of which is 11 initially. After that, Little L shows 22 types of queries:

  • MULTIPLY l r x : For every i \in [l,r]i∈[l,r] (1\le l\le r\le n1≤lrn), multiply a_ia**i by xx (2 \le x \le 102≤x≤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),lirmax{pa**imax{potp(a**i)}} (1≤lrn),

where pp is prime.

Now you need to perform q~(1 \le q \le 10^5)q (1≤q≤105) 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 yy the value you‘ve calculated.

Input

The first line contains two integers n~(1 \le n \le 10^5)n (1≤n≤105) and q~(1 \le q \le 10^5)q (1≤q≤105), the number of integers and the number of queries.

Each of the next qq lines contains one type of query described above.

Output

For each “MAX” query, output one line in the format of ANSWER y, where yy 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 mm and nn are non-zero integers, or more generally, non-zero elements of an integral domain, it is said that mm divides nn if there exists an integer kk, or an element kk of the integral domain, such that m \times k=nm×k=n, and this is written as m \mid nmn.

编辑代码

题面直接复制过来有点拉。

每次把乘数分解质因子 因为乘数在1到10 因此最后对每个数分解质因数只有四个质数 可以开四棵线段树 分别统计a[i]的这个质因子个数 维护区间最大值。最后对四棵线段树的查询结果取max即可。别忘记懒标记。

#include <bits/stdc++.h>
#define int long long
#define N 100005
using namespace std;
int n, q;
int a[100005];
struct SegmentTree {
	int p, l, r;
	int add, dat;
} t[4][N * 4 + 5];
void build(int id, int p, int l, int r) {
	t[id][p].l = l, t[id][p].r = r, t[id][p].add = 0;
	if(t[id][p].l == t[id][p].r) {
		t[id][p].dat = 0;
		return;
	}
	int mid = (l + r) >> 1;
	build(id, 2 * p, l, mid);
	build(id, 2 * p + 1, mid + 1, r);
	t[id][p].dat = max(t[id][2 * p].dat, t[id][2 * p + 1].dat);
}
void spread(int id, int p) {
	if(t[id][p].add) {
		t[id][2 * p].dat += t[id][p].add;
		t[id][2 * p + 1].dat += t[id][p].add;
		t[id][2 * p].add += t[id][p].add;
		t[id][2 * p + 1].add += t[id][p].add;
		t[id][p].add = 0;
	}
}
void change(int id, int p, int l, int r, int x) {
	if(t[id][p].l >= l && t[id][p].r <= r) {
		t[id][p].dat += x;
		t[id][p].add += x;
		return;
	}
	spread(id, p);
	int mid = (t[id][p].l + t[id][p].r) >> 1;
	if(l <= mid) {
		change(id, 2 * p, l, r, x);
 	}
	if(r > mid) {
		change(id, 2 * p + 1, l, r, x);
	}
	t[id][p].dat = max(t[id][2 * p].dat, t[id][2 * p + 1].dat);
}
int ask(int id, int p, int l, int r) {
	if(t[id][p].l >= l && t[id][p].r <= r) {
		return t[id][p].dat;
	}
	spread(id, p);
	int mid = (t[id][p].l + t[id][p].r) >> 1;
	int ans = -0x3f3f3f3f;
	if(l <= mid) {
		ans = max(ans, ask(id, 2 * p, l, r));
	}
	if(r > mid) {
		ans = max(ans, ask(id, 2 * p + 1, l, r));
	}
	return ans;
}
//每次把乘数分解质因子 因为乘数在1到10 因此只有四个质数 可以开四棵线段树 分别统计a[i]的这个质因子个数 维护区间最值 
//最后对四棵线段树的查询结果取max即可。
signed main() {
	//freopen("data.txt", "r", stdin);
	cin >> n >> q;
	for(int i = 1; i <= n; i++) a[i] = 0;
	build(0, 1, 1, n);
	build(1, 1, 1, n);
	build(2, 1, 1, n);
	build(3, 1, 1, n);
	for(int i = 1; i <= q; i++) {
		string s;
		cin >> s;
		if(s == "MULTIPLY") {
			int l, r, x;
			cin >> l >> r >> x;
			int p[4], cnt[4];
			for(int i = 0; i < 4; i++) cnt[i] = 0;
			p[0] = 2, p[1] = 3, p[2] = 5, p[3] = 7;
			for(int i = 0; i < 4; i++) {
				while(x % p[i] == 0) {
					++cnt[i];
					x /= p[i];
				}
				change(i, 1, l, r, cnt[i]);
			}
		} else {
			int l, r;
			cin >> l >> r;
			int ans = -0x3f3f3f3f;
			for(int i = 0; i < 4; i++) {
				ans = max(ans, ask(i, 1, l, r));
			}
			cout << "ANSWER " << ans << endl;
		}
	}
	return 0;
}

2019 ICPC Asia Yinchuan Regional G. Pot!!(线段树/数论)

原文:https://www.cnblogs.com/lipoicyclic/p/14746433.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!