题目链接:G Pot!!
题意
给你一个长度为n初始化为1的序列。你有两个操作
- 给区间[l,r]里每一个数乘以v。
- 查询区间里的一个最大值。
这个最大值题目中有定义,其实知道唯一分解定理就不难理解,这个最大值就是一个数唯一分解后,所有质因数里最大的幂次。然后在区间[l,r]里面找每个数最大幂次的最大值。
题解
本题的入手点在于给区间乘以一个数v的大小≤10,10以内的数唯一分解后,无非2、3、5、7四种。言外之意,无论我如何乘,都只能是2,3,5,7这四个数的幂次方。我们可以建立一个线段树维护5个点,2,3,5,7的幂次以及这四个幂次中的最大值。
注意我们在设置lazy标记的时候也要设立2,3,5,7的幂次,往下push完重置为0即可。
代码
一颗线段是维护4个点
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double ld;
//typedef int fuck;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define lowbit(x) x&-x
//#define int long long
const double PI=acos(-1.0);
const double eps=1e-6;
const ll mod=1e9+7;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
const int maxm=100+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int n,q;
struct Tree
{
int maxx;
int num2,num3,num5,num7;
}tree[maxn<<2];
struct Lazy
{
int num;
int num2,num3,num5,num7;
}lazy[maxn<<2];
int prime[5]={
2,3,5,7};
void pushup(int p)
{
tree[p].maxx=max(tree[p*2].maxx,tree[p*2+1].maxx);
tree[p].num2=max(tree[p*2].num2,tree[p*2+1].num2);
tree[p].num3=max(tree[p*2].num3,tree[p*2+1].num3);
tree[p].num5=max(tree[p*2].num5,tree[p*2+1].num5);
tree[p].num7=max(tree[p*2].num7,tree[p*2+1].num7);
}
void build(int p,int l,int r)
{
lazy[p].num=lazy[p].num2=lazy[p].num3=lazy[p].num5=lazy[p].num7=0;
if(l==r) {
tree[p].maxx=tree[p].num2=tree[p].num3=tree[p].num5=tree[p].num7=0;
return ;
}
int mid=l+(r-l)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
pushup(p);
}
void pushdown(int p)
{
if(!lazy[p].num) return ;
lazy[p*2].num=lazy[p*2+1].num=1;
lazy[p*2].num2+=lazy[p].num2;
lazy[p*2].num3+=lazy[p].num3;
lazy[p*2].num5+=lazy[p].num5;
lazy[p*2].num7+=lazy[p].num7;
lazy[p*2+1].num2+=lazy[p].num2;
lazy[p*2+1].num3+=lazy[p].num3;
lazy[p*2+1].num5+=lazy[p].num5;
lazy[p*2+1].num7+=lazy[p].num7;
tree[p*2].num2+=lazy[p].num2, tree[p*2].maxx=max(tree[p*2].maxx,tree[p*2].num2);
tree[p*2].num3+=lazy[p].num3, tree[p*2].maxx=max(tree[p*2].maxx,tree[p*2].num3);
tree[p*2].num5+=lazy[p].num5, tree[p*2].maxx=max(tree[p*2].maxx,tree[p*2].num5);
tree[p*2].num7+=lazy[p].num7, tree[p*2].maxx=max(tree[p*2].maxx,tree[p*2].num7);
tree[p*2+1].num2+=lazy[p].num2, tree[p*2+1].maxx=max(tree[p*2+1].maxx,tree[p*2+1].num2);
tree[p*2+1].num3+=lazy[p].num3, tree[p*2+1].maxx=max(tree[p*2+1].maxx,tree[p*2+1].num3);
tree[p*2+1].num5+=lazy[p].num5, tree[p*2+1].maxx=max(tree[p*2+1].maxx,tree[p*2+1].num5);
tree[p*2+1].num7+=lazy[p].num7, tree[p*2+1].maxx=max(tree[p*2+1].maxx,tree[p*2+1].num7);
lazy[p].num2=lazy[p].num3=lazy[p].num5=lazy[p].num7=0;
lazy[p].num=0;
}
void multi(int p,int l,int r,int ml,int mr,int v)
{
if(ml<=l && mr>=r)
{
lazy[p].num=1;
int tmp=v;
for(int i=0;i<4;i++)
{
int cnt=0;
while(tmp%prime[i]==0)
{
tmp/=prime[i];
cnt++;
}
if(i==0) {
lazy[p].num2+=cnt,tree[p].num2+=cnt, tree[p].maxx=max(tree[p].maxx,tree[p].num2); }
if(i==1) {
lazy[p].num3+=cnt,tree[p].num3+=cnt, tree[p].maxx=max(tree[p].maxx,tree[p].num3); }
if(i==2) {
lazy[p].num5+=cnt,tree[p].num5+=cnt, tree[p].maxx=max(tree[p].maxx,tree[p].num5); }
if(i==3) {
lazy[p].num7+=cnt,tree[p].num7+=cnt, tree[p].maxx=max(tree[p].maxx,tree[p].num7); }
}
return ;
}
pushdown(p);
int mid=l+(r-l)/2;
if(ml<=mid) multi(p*2, l, mid, ml, mr, v);
if(mr>mid) multi(p*2+1, mid+1, r, ml, mr, v);
pushup(p);
}
int query_mul(int p,int l,int r,int ql,int qr)
{
if(ql<=l && qr>=r) return tree[p].maxx;
int mid=l+(r-l)/2;
pushdown(p);
int ans=0;
if(ql<=mid) ans=max(ans,query_mul(p*2, l, mid, ql, qr));
if(qr>mid) ans=max(ans,query_mul(p*2+1, mid+1, r, ql, qr));
tree[p].maxx=max(tree[p*2].maxx,tree[p*2+1].maxx);
return ans;
}
int main()
{
scanf("%d%d",&n,&q);
build(1, 1, n);
while(q--)
{
char s[15];
scanf("%s",s);
if(s[1]=='U')
{
int l,r,v; scanf("%d%d%d",&l,&r,&v);
multi(1, 1, n, l, r, v);
}
else
{
int l,r; scanf("%d%d",&l,&r);
printf("ANSWER %d\n",query_mul(1, 1, n, l, r));
}
}
}
//5 100
//MULTIPLY 2 3 8
//MULTIPLY 1 4 8
//m 1 5
建立4棵线段树
#include<iostream>
#include <sstream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double ld;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define lowbit(x) x&-x
//#define int long long
const double PI=acos(-1.0);
const double eps=1e-6;
const ll mod=1e9+7;
const ll inf=1e18;
const int maxn=1e5+10;
const int maxm=100+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
ll num2[maxn<<2],num3[maxn<<2],num5[maxn<<2],num7[maxn<<2];
ll add2[maxn<<2],add3[maxn<<2],add5[maxn<<2],add7[maxn<<2];
char s[15];
int prime[4]={
2,3,5,7};
void pushup(int p)
{
num2[p]=max(num2[p*2],num2[p*2+1]);
num3[p]=max(num3[p*2],num3[p*2+1]);
num5[p]=max(num5[p*2],num5[p*2+1]);
num7[p]=max(num7[p*2],num7[p*2+1]);
}
void build(int p,int l,int r)
{
if(l==r) {
num2[l]=num3[l]=num5[l]=num7[l]=0; return ;}
int mid=(l+r)/2;
build(p*2, l, mid);
build(p*2+1, mid+1, r);
pushup(p);
}
void pushdown(int p)
{
add2[p*2]+=add2[p]; add2[p*2+1]+=add2[p];
num2[p*2]+=add2[p]; num2[p*2+1]+=add2[p];
add3[p*2]+=add3[p]; add3[p*2+1]+=add3[p];
num3[p*2]+=add3[p]; num3[p*2+1]+=add3[p];
add5[p*2]+=add5[p]; add5[p*2+1]+=add5[p];
num5[p*2]+=add5[p]; num5[p*2+1]+=add5[p];
add7[p*2]+=add7[p]; add7[p*2+1]+=add7[p];
num7[p*2]+=add7[p]; num7[p*2+1]+=add7[p];
add2[p]=add3[p]=add5[p]=add7[p]=0;
}
void add(int p,int l,int r,int addl,int addr,int v)
{
if(addl<=l && addr>=r) {
for(int i=0;i<4;i++)
{
int cnt=0;
if(v%prime[i]==0)
{
while(v%prime[i]==0){
cnt++; v/=prime[i];}
}
if(i==0) {
num2[p]+=cnt; add2[p]+=cnt;}
if(i==1) {
num3[p]+=cnt; add3[p]+=cnt;}
if(i==2) {
num5[p]+=cnt; add5[p]+=cnt;}
if(i==3) {
num7[p]+=cnt; add7[p]+=cnt;}
}
return ;
}
pushdown(p);
int mid=(l+r)>>1;
if(addl<=mid) add(p*2, l, mid, addl, addr, v);
if(addr>mid) add(p*2+1, mid+1, r, addl, addr, v);
pushup(p);
}
ll query(int p,int l,int r,int ql,int qr)
{
if(ql<=l && qr>=r) {
return max(num2[p],max(num3[p],max(num5[p],num7[p]))); }
pushdown(p);
int mid=(l+r)>>1;
ll maxx=-1;
if(ql<=mid) maxx=max(maxx, query(p*2, l, mid, ql, qr));
if(qr>mid) maxx=max(maxx, query(p*2+1, mid+1, r, ql, qr));
pushup(p);
return maxx;
}
int main()
{
int n,q;
scanf("%d%d",&n,&q);
build(1, 1, n);
while(q--)
{
scanf("%s",s);
if(s[1]=='U')
{
int l,r,v;
scanf("%d%d%d",&l,&r,&v);
add(1, 1, n, l, r, v);
}
else
{
int l,r; scanf("%d%d",&l,&r);
printf("ANSWER %lld\n",query(1, 1, n, l, r));
}
}
}