2019 ICPC Asia Yinchuan Regional G. Pot!!

2019 ICPC Asia Yinchuan Regional

【题目大意】

【解题思路】
在线段树上打4个标记分别表示将节点权值分解为2,4,5,7的个数,或者开4颗线段树也可

【AC代码】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
inline ll max(ll a, ll b) { return a > b ? a : b; }
struct Tree
{
	int l, r;
	ll flag2;
	ll flag3;
	ll flag5;
	ll flag7;
	ll lazy[5];
}tree[maxn];
inline void pushdown(int root)
{
	tree[root].flag2 += tree[root].lazy[1];
	tree[root].flag3 += tree[root].lazy[2];
	tree[root].flag5 += tree[root].lazy[3];
	tree[root].flag7 += tree[root].lazy[4];
	for (int i = 1; i <= 4; ++i)
	{
		tree[root << 1].lazy[i] += tree[root].lazy[i];
		tree[root << 1 | 1].lazy[i] += tree[root].lazy[i];
		tree[root].lazy[i] = 0;
	}
}
inline void build(int root, int l, int r)
{
	tree[root].l = l;
	tree[root].r = r;
	tree[root].flag2 = tree[root].flag3 = tree[root].flag5 = tree[root].flag7 = 0;
	for (int i = 1; i <= 4; ++i)
	{
		tree[root].lazy[i] = 0;
	}
	if (l == r) return;
	register int mid = (l + r) >> 1;
	build(root << 1, l, mid);
	build(root << 1 | 1, mid + 1, r);
}
inline void update(int root, int l, int r, ll val)
{
	if (l <= tree[root].l && tree[root].r <= r)
	{
		while (val % 2 == 0)
		{
			++tree[root].lazy[1];
			val /= 2;
		}
		while (val % 3 == 0)
		{
			++tree[root].lazy[2];
			val /= 3;
		}
		while (val % 5 == 0)
		{
			++tree[root].lazy[3];
			val /= 5;
		}
		while (val % 7 == 0)
		{
			++tree[root].lazy[4];
			val /= 7;
		}
		pushdown(root);
		return;
	}
	pushdown(root);
	register int mid = (tree[root].l + tree[root].r) >> 1;
	if (mid >= r) update(root << 1, l, r, val);
	else if (mid < l) update(root << 1 | 1, l, r, val);
	else
	{
		update(root << 1, l, mid, val);
		update(root << 1 | 1, mid + 1, r, val);
	}
	tree[root].flag2 = max(tree[root].flag2, max(tree[root << 1].flag2, tree[root << 1 | 1].flag2));
	tree[root].flag3 = max(tree[root].flag3, max(tree[root << 1].flag3, tree[root << 1 | 1].flag3));
	tree[root].flag5 = max(tree[root].flag5, max(tree[root << 1].flag5, tree[root << 1 | 1].flag5));
	tree[root].flag7 = max(tree[root].flag7, max(tree[root << 1].flag7, tree[root << 1 | 1].flag7));
}
inline ll query(int root, int l, int r)
{
	pushdown(root);
	if (l <= tree[root].l && tree[root].r <= r)
	{
		return max(max(tree[root].flag2, tree[root].flag3), max(tree[root].flag5, tree[root].flag7));
	}
	register int mid = (tree[root].l + tree[root].r) >> 1;
	if (mid >= r) return query(root << 1, l, r);
	else if (mid < l) return query(root << 1 | 1, l, r);
	else return max(query(root << 1, l, mid), query(root << 1 | 1, mid + 1, r));
}
int main()
{
	register int n, m;
	scanf("%d%d", &n, &m);
	build(1, 1, n);
	register char s[10];
	register int l, r;
	register ll val;
	while (m--)
	{
		scanf(" %s", s);
		scanf("%d%d", &l, &r);
		if (strcmp(s, "MULTIPLY") == 0)
		{
			scanf("%lld", &val);
			update(1, l, r, val);
		}
		else printf("ANSWER %lld\n", query(1, l, r));
	}
	return 0;
}
发布了40 篇原创文章 · 获赞 2 · 访问量 3225

猜你喜欢

转载自blog.csdn.net/weixin_44211980/article/details/104088954