题解:
欧拉函数线性筛打表,通过树状数组进行区间修改和求区间和的操作
通过扩展欧拉定理进行降幂操作,具体可以看另一篇博客关于欧拉降幂的粗略理解
https://blog.csdn.net/weixin_43916296/article/details/100396671
代码:
做这题时打表数据范围开小了,一直样例爆炸。。
太菜了。。长教训了
#include<iostream>
#include<algorithm>
#include<cmath>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<map>
#include<set>
#include<stack>
#define debug cout<<"*"<<endl;
#define input(x) scanf("%d",&x)
#define output(x) printf("%d\n",x);
#define llinput(x) scanf("%lld",&x)
#define lloutput(x) printf("%lld\n",x);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<string,int> psi;
typedef pair<char,char> pcc;
const int mod=1e9+7;
const int INF=1e9+7;
const int maxn=2e7+700;
const double PI=acos(-1);
const int N=3007;
ll sum[500007];
ll lowbit(ll d)
{
return d&(-d);
}
void add(ll pos,ll x)
{
while(pos<maxn)
{
sum[pos]+=x;
pos+=lowbit(pos);
}
}
ll sum_(ll pos)
{
ll ans=0;
while(pos)
{
ans+=sum[pos];
pos-=lowbit(pos);
}
return ans;
}
ll prime[maxn];
ll oula[maxn];
bool vis[maxn];
ll cot=0;
void Init()
{
oula[1]=1;
memset(vis,false,sizeof(vis));
for(ll i=2;i<maxn;i++)
{
if(!vis[i]){prime[++cot]=i;oula[i]=i-1;}
for(ll j=1;j<=cot&&i*prime[j]<maxn;j++)
{
vis[i*prime[j]]=true;
if(i%prime[j]==0)
{
oula[i*prime[j]]=oula[i]*prime[j];
break;
}
oula[i*prime[j]]=oula[i]*(prime[j]-1);
}
}
}
ll modu(ll a,ll b)
{
return (a>b?(a%b+b):a);
}
ll qpow(ll a,ll b,ll mod)
{
ll ans=1;
a=modu(a,mod);
while(b)
{
if(b&1) ans=modu(ans*a,mod);
a=modu(a*a,mod);
b>>=1;
//cout<<"*";
}
return ans;
}
ll dfs(ll l,ll r,ll m)
{
ll summ=sum_(l);
//cout<<l<<" "<<r<<" "<<m<<" "<<summ<<endl;
if(l==r||m==1)
return modu(summ,m);
//debug;
//cout<<l+1<<" "<<r<<" "<<oula[m]<<endl;
ll res=dfs(l+1,r,oula[m]);
return qpow(summ,res,m);
}
int main()
{
Init();
ll n,m;
llinput(n);llinput(m);
ll tmp=0,a;
for(ll i=1;i<=n;i++)
{
llinput(a);
add(i,a-tmp);
tmp=a;
//add(i+1,-a);
}
for(ll i=1;i<=m;++i)
{
ll oper,l,r,x;
llinput(oper);llinput(l);llinput(r);llinput(x);
if(oper==1)
{
add(l,x);
add(r+1,-x);
}
else if(oper==2)
{
ll ans=dfs(l,r,x)%x;
lloutput(ans);
}
}
return 0;
}