83分求助
查看原帖
83分求助
632131
Kevin911楼主2023/10/14 00:17

第六个点WA了

//根据a数组的值域,可以质因数分组后转化为状态压缩后存入线段树 
#include<bits/stdc++.h>
#define int unsigned long long
using namespace std;
const int maxn=4e5+10,mod=1e9+7;
int a[maxn],id[maxn],p[maxn],s[maxn],cnt;
int ta[maxn<<2],mul[maxn<<2];
bool isprime(int x)
{
	for(int i=2;i*i<=x;i++)
		if(x%i==0) return 0;
	return 1;
}
int po(int x,int y)
{
	int res=1,r=x;
	for(int i=y;i;i>>=1)
	{
		if(i&1) res=res*r%mod;
		r=r*r%mod;
	}
	return res;
}
void pre()
{
	for(int i=2;i<=300;i++)
		if(isprime(i))
		{
			id[i]=++cnt;
			p[cnt]=i;
		}
	for(int i=1;i<=300;i++)
	{
		int k=i;
		for(int j=2;j*j<=k;j++)
		{
			int cnt=0;
			while(k%j==0) k/=j,cnt++;
			if(cnt) s[i]|=1ll<<id[j];
		}
		if(k>1) s[i]|=1ll<<id[k];
	}
}
struct seg
{
	int tag,sum;
}tr[maxn<<2];
void push_up(int id)
{
	tr[id].sum=tr[id*2].sum|tr[id*2+1].sum;
	mul[id]=mul[id*2]*mul[id*2+1]%mod;
}
void push_down(int id)
{
	if(!tr[id].tag) return;
	tr[id*2].tag|=tr[id].tag,tr[id*2+1].tag|=tr[id].tag;
	tr[id*2].sum|=tr[id].tag,tr[id*2+1].sum|=tr[id].tag;
	tr[id].tag=0;
}
void push_down_mul(int id,int l,int r)
{
	if(ta[id]==1) return;
	int mid=(l+r)/2;
	mul[id*2]*=po(ta[id],mid-l+1),mul[id*2+1]*=po(ta[id],r-mid);
	mul[id*2]%=mod,mul[id*2+1]%=mod;
	ta[id*2]=ta[id];
	ta[id*2+1]=ta[id];
	ta[id]=1;
}
void build(int id,int l,int r)
{
	tr[id].tag=tr[id].sum=0;
	ta[id]=1;
	if(l==r)
	{
		tr[id].sum=s[a[l]];
		mul[id]=a[l];
		return;
	}
	int mid=(l+r)/2;
	build(id*2,l,mid);
	build(id*2+1,mid+1,r);
	push_up(id);
}
void update(int id,int l,int r,int L,int R,int c)
{
	if(l>R||r<L) return;
	if(l>=L&&r<=R)
	{
		tr[id].tag|=s[c];
		tr[id].sum|=s[c];
		mul[id]*=po(c,r-l+1);
		mul[id]%=mod;
		ta[id]*=c;
		ta[id]%=mod;
		return;
	}
	push_down(id);
	push_down_mul(id,l,r);
	int mid=(l+r)/2;
	update(id*2,l,mid,L,R,c);
	update(id*2+1,mid+1,r,L,R,c);
	push_up(id);
}
int querysum(int id,int l,int r,int L,int R)
{
	if(l>R||r<L) return 0;
	if(l>=L&&r<=R) return tr[id].sum;
	push_down(id);
	push_down_mul(id,l,r);
	int mid=(l+r)/2;
	return querysum(id*2,l,mid,L,R)|querysum(id*2+1,mid+1,r,L,R);
}
int querymul(int id,int l,int r,int L,int R)
{
	if(l>R||r<L) return 1;
	if(l>=L&&r<=R) return mul[id];
	push_down(id);
	push_down_mul(id,l,r);
	int mid=(l+r)/2;
	return querymul(id*2,l,mid,L,R)*querymul(id*2+1,mid+1,r,L,R)%mod;
}
signed main()
{
//	cout<<po(3,5)*po(2,60)%mod<<endl;
	pre();
//	for(int i=1;i<=300;i++) cout<<s[i]<<' ';
//	cout<<endl;
	int n,q;
	cin>>n>>q;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,1,n);
//	cout<<querymul(1,1,n,1,4)<<endl;
//	return 0;
//	cout<<tr[6].sum<<endl;
//	cout<<query(1,1,n,3,3)<<endl;
	for(int i=1;i<=q;i++)
	{
		string str;
		cin>>str;
		if(str=="MULTIPLY")
		{
			int l,r,x;
			cin>>l>>r>>x;
			update(1,1,n,l,r,x);
		}
		if(str=="TOTIENT")
		{
			int l,r;
			cin>>l>>r;
			int k=querysum(1,1,n,l,r),ans=querymul(1,1,n,l,r);
			//cout<<k<<' '<<ans<<' ';
			for(int i=k;i;i-=i&(-i))
			{
				int r=log2(i&(-i));
				ans=ans*po(p[r],mod-2)%mod*(p[r]-1)%mod;
			}
			cout<<ans<<endl;
		}
	}
	return 0;
}
/*
7 7
119 251 93 98 71 98 175
MULTIPLY 7 7 250
MULTIPLY 5 7 70
MULTIPLY 5 5 242
MULTIPLY 3 3 66
MULTIPLY 4 7 232
MULTIPLY 7 7 2
TOTIENT 2 5
*/
2023/10/14 00:17
加载中...