集训营第二次考欧拉降幂了Orz
首先不管n,我们就算能选[1,m]的取值的时候的答案。和B题差不多的idea,我们能想到答案其实是,这是一个n+1次的多项式,如果说m很大的话,我们当然不能直接算,但是,我们可以利用拉格朗日插值法求出这个式的值。建议先学习下拉格朗日插值法。
之后,考虑的情况,我们当然不能直接算这个m,那么,题目给了模数,我们考虑只求m mod p的值,那么,考虑如何利用f(m mod p)求f(m).因为为n+1次多项式,那么,我们设,则,,二项式定理展开后,发现,因此,我们只需要求
对于,我们考虑欧拉降幂求即可。
这道题需要学的主要是欧拉降幂的写法,这里所用的EXP函数的方法,或者是官方题解中的预处理都是可以使用的方法,又或者是使用我第一场题解中的取对数的方法都是可行的。具体可以看下我的提交记录。

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>
void read(T&x){
    x=0;
    char ch=getchar();
    int f=1;
    while(!isdigit(ch)){
        if(ch=='-')f*=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        x=x*10+(ch-'0');
        ch=getchar();
    }x*=f;
}
template<typename T>
void write(T x){
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
//===============================================================
#define int ll
#define MOD(x) (((x)%p+p)%p)
#define modit(a,b) ((a)>=(b)?(a)%(b)+(b):(a))
const int maxn=2e5+10;
int n,p;
int mul(int x,int y,int mod=::p){
    return 1ll*x*y%p;
}

int add(int x,int y,int mod=::p){
    return ((x+y)%p+p)%p;
}

ll ksm(ll a,ll n,ll p=::p){
    ll res=1;
    while(n){
        if(n&1)res=res*a%p;
        a=a*a%p;
        n>>=1;
    }
    return res;
}
unordered_map<int,int>mp;
int phi(int x){
    int bak=x;
    if(mp.count(bak))return mp[bak];
    int res=x;
    for(int i=2;i*i<=x;++i){
        if(x%i==0){
            res=res-res/i;
            while(x%i==0)x/=i;
        }
    }
    if(x>1)res=res-res/x;
    return mp[bak]=res;
}

int EXP(int a,int n,int p){
    int res=1;
    while(n){
        if(n&1)res=modit(res*a,p);
        a=modit(a*a,p);
        n>>=1;
    }
    return res;
}

int ex_euler(int n,int mod){
    if(mod==1)return 1;
    return ksm(n,ex_euler(n,phi(mod))+phi(mod),mod);
}
int f[maxn];
int fac[maxn],finv[maxn];
void init(int f[]){
    int lim=n+2;
    for(int i=1;i<=lim;++i){
        f[i]=MOD(f[i-1]+MOD(ksm(i,n+1)-i*ksm(i-1,n)));
    }
    fac[0]=1;
    for(int i=1;i<min(p,maxn);++i)fac[i]=mul(fac[i-1],i);
    finv[min(p-1,maxn-1)]=ksm(fac[min(p-1,maxn-1)],p-2,p);
    for(int i=min(p-2,maxn-2);i>=0;--i)finv[i]=mul(finv[i+1],(i+1));
}
int pre[maxn],suf[maxn];
ll solve(int y[],int n,int x){
    int lim=n+1;
    if(x<=lim)return y[x];
    pre[1]=1,suf[lim]=1;
    for(int i=2;i<=lim;++i)pre[i]=pre[i-1]*(x-(i-1))%p,pre[i]=(pre[i]%p+p)%p;
    for(int i=lim-1;i>=0;--i)suf[i]=suf[i+1]*(x-(i+1))%p,suf[i]=(suf[i]%p+p)%p;
    int res=0;
    for(int i=1;i<=lim;++i){
        int sig=((lim-i)&1?(-1):1);
        ll up=MOD(MOD(sig*suf[i]*pre[i])*f[i]);
        ll down=MOD(finv[i-1]*finv[lim-i]);
        res=(res+mul(up,down))%p;
        res=(res%p+p)%p;
        //res=add(res,MOD(sig*mul(mul(suf[i],pre[i]),mul(finv[i],finv[lim-i]))));
    }
    return res;
}

signed main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    read(n),read(p);
    int m=ex_euler(n,p);
    init(f);
    int res=0;
    cout<<solve(f,n+1,m)<<endl;
    return 0;
}