洛谷 P3747 [六省联考 2017] 相逢是问候
欧拉降幂最多只会迭代到第 \(k = \text O (\log p)\) 次模数就会变成 \(1\)(证明见这里)。故一个数被操作超过 \(k\) 次就会变为一个定值。
于是用线段树维护出操作还没有满 \(k\) 次的位置,每次暴力修改并计算,均摊下来只有 \(nk\) 次。光速幂可以预处理。
时间复杂度 \(\text O (k \sqrt p + nk \log n + nk ^ 2)\)。
#include<cstdio>
#include<cmath>
#define N 50005
#define M 55
using namespace std;
int n,m,p,c,k,a[N],mo[M];
int pw[M][N],Pw[M][N];
int mod(long long x,int p) {
if(x<p) return x;
return x%p+p;
}
int phi(int x) {
int res=x;
for(int i=2;i<=x/i;i++) if(x%i==0) {
res=res/i*(i-1);
while(x%i==0) x/=i;
}
if(x>1) res=res/x*(x-1);
return res;
}
int qqpow(int x,int y,int p) {
return mod(1ll*pw[p][y&(1<<14)-1]*Pw[p][y>>14],mo[p]);
}
int calc(int x,int p,int d) {
if(p>d) return mod(x,mo[p]);
return qqpow(x,calc(x,p+1,d),p);
}
struct segment_tree {
struct st {
int l,r,c,cnt,sum; bool tag;
#define l(p) tr[p].l
#define r(p) tr[p].r
#define c(p) tr[p].c
#define cnt(p) tr[p].cnt
#define sum(p) tr[p].sum
#define tag(p) tr[p].tag
} tr[N*4];
void update(int p) {
sum(p)=(sum(p*2)+sum(p*2+1))%mo[1];
tag(p)=tag(p*2)|tag(p*2+1);
}
void build(int p,int l,int r) {
l(p)=l,r(p)=r,tag(p)=1;
if(l==r) {c(p)=sum(p)=a[l]; return;}
int mid=l+r>>1;
build(p*2,l,mid),build(p*2+1,mid+1,r);
update(p);
}
void modify(int p,int l,int r) {
if(!tag(p)) return;
if(l(p)==r(p)) {
cnt(p)++,sum(p)=calc(c(p),1,cnt(p))%mo[1],tag(p)=cnt(p)<k;
return;
}
if(l<=r(p*2)) modify(p*2,l,r);
if(r>=l(p*2+1)) modify(p*2+1,l,r);
update(p);
}
int ask(int p,int l,int r) {
if(l<=l(p)&&r>=r(p)) return sum(p);
if(r<=r(p*2)) return ask(p*2,l,r);
if(l>=l(p*2+1)) return ask(p*2+1,l,r);
return (ask(p*2,l,r)+ask(p*2+1,l,r))%mo[1];
}
} t1;
int main() {
scanf("%d%d%d%d",&n,&m,&p,&c);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
while(p>1) mo[++k]=p,p=phi(p);
mo[++k]=p;
for(int i=1;i<=k;i++) {
int w=1;
for(int j=0;j<1<<14;j++) pw[i][j]=w,w=mod(1ll*w*c,mo[i]);
int cc=w; w=1;
for(int j=0;j<1<<14;j++) Pw[i][j]=w,w=mod(1ll*w*cc,mo[i]);
}
mo[k+1]=1,t1.build(1,1,n);
for(int i=1,op,x,y;i<=m;i++) {
scanf("%d%d%d",&op,&x,&y);
if(!op) t1.modify(1,x,y);
else printf("%d\n",t1.ask(1,x,y));
}
return 0;
}

浙公网安备 33010602011771号