Yinchuan Regional 2019
Pot!!
题目链接
题意:
有一个长为 n n n 的数组 a a a。初始全为 1 1 1 ,有两种操作:
MULTIPLY l r x
:表示给区间 [ l , r ] [l,r] [l,r] 上的数全部乘以 x x\quad x ( 2 ≤ x ≤ 10 ) (2\le x\le10) (2≤x≤10)MAX l r
:表示询问区间 [ l , r ] [l,r] [l,r] 某个数的最大 质因数指数的最大值是多少。
原文:
对一个质数
p
p
p,如果
p
m
∣
n
p^m|n
pm∣n 并且
p
m
+
1
∤
n
p^{m+1}\not|n
pm+1∣n,则
p
o
t
p
(
n
)
=
m
pot_p(n) = m
potp(n)=m,第二种操作就是计算 :
m
a
x
l
≤
i
≤
r
{
m
a
x
p
∣
a
i
{
p
o
t
p
(
a
i
)
}
}
(
1
≤
l
≤
r
≤
n
)
max_{\,l\le i\le r}\{max_{\,p|a_i}\{pot_p(a_i)\}\}(1\le l\le r\le n)
maxl≤i≤r{maxp∣ai{potp(ai)}}(1≤l≤r≤n)的值
思路:
发现每个数的质因数只有 2 , 3 , 5 , 7 2,3,5,7 2,3,5,7,我们给一段区间所有数乘上 x x x 就相当于给这段区间所有数的四种质因子个数加上 x x x 的四种质因数个数,查询就是查询最大值。线段树模板题。
code:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1e5+5;
int n,Q;
struct segement_tree{
#define ls p<<1
#define rs p<<1|1
int n;
struct info{
int l2,l3,l5,l7;
info(int x=0){
l2=l3=l5=l7=0;
switch(x){
case 0:break;
case 2:l2=1;break;
case 3:l3=1;break;
case 4:l2=2;break;
case 5:l5=1;break;
case 6:l2=1;l3=1;break;
case 7:l7=1;break;
case 8:l2=3;break;
case 9:l3=2;break;
case 10:l2=1;l5=1;break;
}
}
info operator+(info x){
info t;
t.l2=l2+x.l2;
t.l3=l3+x.l3;
t.l5=l5+x.l5;
t.l7=l7+x.l7;
return t;
}
};
struct Node{
int mx;
int n2,n3,n5,n7;
info lazy;
Node(){};
}t[maxn<<2];
void f(int p,info x){
t[p].n2+=x.l2;
t[p].n3+=x.l3;
t[p].n5+=x.l5;
t[p].n7+=x.l7;
t[p].lazy=t[p].lazy+x;
t[p].mx=max(max(t[p].n2,t[p].n3),max(t[p].n5,t[p].n7));
}
void push_down(int p){
f(ls,t[p].lazy);
f(rs,t[p].lazy);
t[p].lazy=info();
}
Node merge_Node(Node a,Node b){
Node c;
c.n2=max(a.n2,b.n2);
c.n3=max(a.n3,b.n3);
c.n5=max(a.n5,b.n5);
c.n7=max(a.n7,b.n7);
c.mx=max(max(c.n2,c.n3),max(c.n5,c.n7));
return c;
}
void build(int p,int l,int r){
if(l==r)return;
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
t[p]=merge_Node(t[ls],t[rs]);
}
void build(int _n){
n=_n;
build(1,1,n);
}
void mul(int p,int l,int r,int L,int R,info x){
if(L<=l && r<=R){
f(p,x);
return;
}
push_down(p);
int mid=(l+r)>>1;
if(L<=mid)mul(ls,l,mid,L,R,x);
if(R>mid)mul(rs,mid+1,r,L,R,x);
t[p]=merge_Node(t[ls],t[rs]);
}
void mul(int L,int R,int x){
mul(1,1,n,L,R,info(x));
}
Node query(int p,int l,int r,int L,int R){
if(L<=l && r<=R){
return t[p];
}
push_down(p);
int mid=(l+r)>>1;
if(R<=mid)return query(ls,l,mid,L,R);
if(L>mid)return query(rs,mid+1,r,L,R);
return merge_Node(query(ls,l,mid,L,R),query(rs,mid+1,r,L,R));
}
int query(int L,int R){
Node t=query(1,1,n,L,R);
return t.mx;
}
void print(int p,int l,int r){
printf("[%d,%d] %d\n",l,r,t[p].mx);
printf("%d %d %d %d\n",t[p].n2,t[p].n3,t[p].n5,t[p].n7);
printf("%d %d %d %d\n",t[p].lazy.l2,t[p].lazy.l3,t[p].lazy.l5,t[p].lazy.l7);
if(l==r)return;
int mid=(l+r)>>1;
print(ls,l,mid);
print(rs,mid+1,r);
}
void print(){
print(1,1,n);
}
#undef ls
#undef rs
}tr;
int main(){
cin>>n>>Q;
tr.build(n);
for(int i=1;i<=Q;i++){
string op;
cin>>op;
if(op=="MULTIPLY"){
int l,r,x;
cin>>l>>r>>x;
tr.mul(l,r,x);
}
else {
int l,r;
cin>>l>>r;
cout<<"ANSWER "<<tr.query(l,r)<<endl;
}
}
return 0;
}