[Ynoi Easy Round 2016] 炸脖龙 I
[Ynoi Easy Round 2016] 炸脖龙 I
一道简单的 Ynoi 题。
题意
给定长度为 \(n\) 的序列 \(a\),有 \(m\) 次操作,每次操作有两种形式:
-
区间 \([l,r]\) 加 \(x\)。
-
求 \(a[l]^{a[l+1]^{a[l+2]^{\dots^{a[r]}}}} \bmod p\)。
\(1 \leq n,m \leq 5 \times 10^5\),\(1 \leq p \leq 2 \times 10^7\)。
思路
首先我们需要知道扩展欧拉定理:
\[a^b \equiv
\begin{cases}
a^b && b < \varphi(m)\\
a^{b \bmod \varphi(m) + \varphi(m)} && b \geq \varphi(m)
\end{cases}
(\bmod \space m)
\]
我们发现,对于 \(x\) 不停求 \(\varphi(x)\),最多经过 \(O(\log x)\) 次后变为 \(1\)。所以对于查询操作,实际只有 \(O(\log p)\) 个元素是有用的,暴力查询即可。这也是 Power Tower。
对于区间修改,我们可以使用树状数组维护。\(n\) 和 \(m\) 同阶,最终复杂度 \(O(p + n \log n \log p)\)。
代码
#include<iostream>
#include<cstdio>
using namespace std;
const int N=20000000;
int n,m;
long long num[500010],c[500010],phi[N+10];
void modify(int pos,long long dif){
while(pos<=n){
c[pos]+=dif;
pos+=pos&-pos;
}
}
long long query(int pos){
long long ans=0;
while(pos>=1){
ans+=c[pos];
pos-=pos&-pos;
}
return ans;
}
int tot,prime[N+10];
bool del[N+10];
void init(){
phi[1]=1;
for(int i=2;i<=N;i++){
if(!del[i]){
prime[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot && prime[j]<=N/i;j++){
del[i*prime[j]]=true;
if(i%prime[j]){
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
else{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
}
}
}
long long mod(long long lhs,long long rhs){
if(lhs>=rhs) return lhs%rhs+rhs;
else return lhs;
}
long long pow_mod(long long lhs,long long rhs,long long p){
lhs=mod(lhs,p);
if(rhs==1) return mod(lhs,p);
long long ans=pow_mod(lhs,rhs/2,p);
ans=mod(ans*ans,p);
if(rhs%2==1) ans=mod(ans*lhs,p);
return ans;
}
long long ask(long long l,long long r,long long p){
if(l==r) return mod(query(l),p);
else if(p==1) return 1;
else return pow_mod(query(l),mod(ask(l+1,r,phi[p]),phi[p]),p);
}
int main(){
init();
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
modify(i,num[i]-num[i-1]);
}
while(m--){
int cmd;
scanf("%d",&cmd);
if(cmd==1){
int l,r;
long long dif;
scanf("%d %d %lld",&l,&r,&dif);
modify(l,dif);
modify(r+1,-dif);
}
else{
int l,r;
long long p;
scanf("%d %d %lld",&l,&r,&p);
printf("%lld\n",ask(l,r,p)%p);
}
}
return 0;
}

浙公网安备 33010602011771号