传送门
给定一个长度为n的序列m次操作,操作的种类一共有三种
首先我们注意一下数据的范围,保证数据不超过100,那么很明显素因子特别少一共只有25个,我们可以用线段树维护一下对应素因子的最大值与最小值。更新的话就是单点更新。由于时间比较紧,我们需要把所有的数压到一个 int 中去。
#include <bits/stdc++.h>
using namespace std;
#define lson(id) id<<1
#define rson(id) id<<1|1
int index[110];
const int maxn = 1e5+10;
int p[32];
int cnt ;
void init() {
memset(index,0,sizeof(index));
cnt = 0;
for(int i=2; i<=100; i++) {
bool tag = 1;
for(int j=2; j<i; j++) {
if(i%j==0)
tag=0;
}
if(tag) {
p[cnt++]=i;
}
}
}
int st[30]= {28,25,23,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
inline int Scan() { //输入外挂
int res=0,ch,flag=0;
if((ch=getchar())=='-')
flag=1;
else if(ch>='0'&&ch<='9')
res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')
res=res*10+ch-'0';
return flag?-res:res;
}
inline int mymin(int x,int y) {
return min(x&0x70000000,y&0x70000000)|min(x&0x0e000000,y&0x0e000000)|min(x&0x01800000,y&0x01800000)|min(x&0x00600000,y&0x00600000)|((x&0x001fffff)&(y&0x001fffff));
}
inline int mymax(int x,int y) {
return max(x&0x70000000,y&0x70000000)|max(x&0x0e000000,y&0x0e000000)|max(x&0x01800000,y&0x01800000)|max(x&0x00600000,y&0x00600000)|((x&0x001fffff)|(y&0x001fffff));
}
int trans(int x) {
int y = 0;
for(int i=0; i<cnt; i++) {
int num=0;
while(x%p[i]==0) {
x/=p[i];
num++;
}
y|=num<<st[i];
}
return y;
}
int calc(int x,int d) {
int ans = 1%d;
for(int i=0; i<25; i++) {
int tmp = x>>st[i];
for(int j=0; j<tmp; j++)
ans = ans*p[i]%d;
x=x^(tmp<<st[i]);
}
return ans;
}
struct segtree {
int mmax[maxn<<2];
int mmin[maxn<<2];
void pushup(int id) {
mmin[id]=mymin(mmin[lson(id)],mmin[rson(id)]);
mmax[id]=mymax(mmax[lson(id)],mmax[rson(id)]);
}
void build(int id,int l,int r) {
if(l==r) {
int x=Scan();
mmin[id]=trans(x);
mmax[id]=trans(x);
return;
}
int mid = l+r>>1;
build(lson(id),l,mid);
build(rson(id),mid+1,r);
pushup(id);
}
void update(int id,int x,int val,int l,int r) {
if(l==x&&r==x) {
int tmp = trans(val);
mmin[id]=tmp;
mmax[id]=tmp;
return ;
}
int mid = l+r>>1;
if(mid>=x) update(lson(id),x,val,l,mid);
else update(rson(id),x,val,mid+1,r);;
pushup(id);
}
int lcm(int id,int l,int r,int x,int y) {
if(l==x&&r==y) {
return mmax[id];
}
int mid = l+r>>1;
if(mid>=y) return lcm(lson(id),l,mid,x,y);
else if(mid<x) return lcm(rson(id),mid+1,r,x,y);
else return mymax(lcm(lson(id),l,mid,x,mid),lcm(rson(id),mid+1,r,mid+1,y));
}
int gcd(int id,int l,int r,int x,int y) {
if(l==x&&r==y) {
return mmin[id];
}
int mid = l+r>>1;
if(mid>=y) return gcd(lson(id),l,mid,x,y);
else if(mid<x) return gcd(rson(id),mid+1,r,x,y);
else return mymin(gcd(lson(id),l,mid,x,mid),gcd(rson(id),mid+1,r,mid+1,y));
}
void output(int id,int l,int r) {
if(l==r) {
cout<<mmax[id]<<" ";
return;
}
int mid = (l+r)>>1;
output(lson(id),l,mid);
output(rson(id),mid+1,r);
}
} T;
int main() {
init();
int n,m;
while(~scanf("%d%d",&n,&m)) {
T.build(1,1,n);
for(int i=0; i<m; i++) {
char s[2];
scanf("%s",s);
if(s[0]=='L') {
int l,r,d;
l=Scan(),r=Scan(),d=Scan();
int ans = T.lcm(1,1,n,l,r);
printf("%d\n",calc(ans,d));
}
if(s[0]=='C') {
int x,val;
x=Scan(),val=Scan();
T.update(1,x,val,1,n);
}
if(s[0]=='G') {
int l,r,d;
l=Scan(),r=Scan(),d=Scan();
int ans = T.gcd(1,1,n,l,r);
printf("%d\n",calc(ans,d));
}
}
}
return 0;
}