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