核心是任意n个数取模,可以用模数的性质,在O(N+logp)的复杂度求出
libre oj
//#include #include #include #include #include #include #include #include using namespace std; typedef long long ll; #define ls (o<<1) #define rs (o<<1|1) #define pb push_back const double PI= acos(-1.0); const int M = 5e6+7; const int mod=1e9+7; /* int head[M],cnt; void init(){cnt=0,memset(head,-1,sizeof(head));} struct EDGE{int to,nxt,val;}ee[M*2]; void add(int x,int y){ee[++cnt].nxt=head[x],ee[cnt].to=y,head[x]=cnt;} */ template void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } ll a[M]; ll sm[M]; ll qpow(ll a,ll b) { ll ans=1; while(b) { if(b&1)ans=ans*a%mod; a=a*a%mod; b/=2; } return ans; } int main() { int n; read(n); ll am;sm[0]=1; for(int i=1;i<=n;i++)read(a[i]),sm[i]=sm[i-1]*a[i]%mod;; am=qpow(sm[n],mod-2); ll lm=1; for(int i=n;i>=1;i--) { ll tp=sm[i-1]*am%mod;//i - n乘积的逆元 tp=tp*lm%mod;//i的逆元 lm=lm*a[i]%mod; a[i]=tp; } ll tp=1,ans=0,x=998244353; for(int i=n;i>=1;i--) { ans=(ans+tp*a[i]%mod)%mod; tp=tp*x%mod; } printf("%lld\n",ans); return 0; }
洛谷:
//#include #include #include #include #include #include #include #include using namespace std; typedef long long ll; #define ls (o<<1) #define rs (o<<1|1) #define pb push_back const double PI= acos(-1.0); const int M = 5e6+7; int mod; /* int head[M],cnt; void init(){cnt=0,memset(head,-1,sizeof(head));} struct EDGE{int to,nxt,val;}ee[M*2]; void add(int x,int y){ee[++cnt].nxt=head[x],ee[cnt].to=y,head[x]=cnt;} */ template void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } ll a[M]; ll sm[M]; ll qpow(ll a,ll b) { ll ans=1; while(b) { if(b&1)ans=ans*a%mod; a=a*a%mod; b/=2; } return ans; } int main() { int n; ll x; read(n),read(mod),read(x); ll am;sm[0]=1; for(int i=1;i<=n;i++)read(a[i]),sm[i]=sm[i-1]*a[i]%mod;; am=qpow(sm[n],mod-2); ll lm=1; for(int i=n;i>=1;i--) { ll tp=sm[i-1]*am%mod;//i - n乘积的逆元 tp=tp*lm%mod;//i的逆元 lm=lm*a[i]%mod; a[i]=tp; } ll tp=x,ans=0; for(int i=1;i<=n;i++) { ans=(ans+tp*a[i]%mod)%mod; tp=tp*x%mod; } printf("%lld\n",ans); return 0; }