5 条题解

  • 7
    @ 2021-10-8 11:33:51

    长度为 11 时,合并后的每项次数分别为 11

    长度为 22 时,合并后的每项次数分别为 1,11,1

    长度为 33 时,合并后的每项次数分别为 1,2,11,2,1

    长度为 44 时,合并后的每项次数分别为 1,3,3,11,3,3,1

    由数学归纳法可以得到,最后的每项次数分别为 $\binom {n-1} 0,\binom {n-1} 1,\binom {n-1} 2,\cdots,\binom {n-1} {n-1}$

    所以为了求解 $\displaystyle \prod_{i=1}^n a_i^{\binom {n-1}i}\bmod P$ ,只需要对组合数模 (P1)(P-1) ,最后跑快速幂合并即可


    由于组合数的模数不是质数,不能直接由逆元推得,可以考虑使用 exLucas,不过那玩意儿难码。

    考虑到组合数的递推式 (n1i)=nii(n1i1)\binom{n-1}i={n-i\over i}\binom {n-1}{i-1} ,而结果恒为整数。故实际上组合数递推过程中除去的结果一定为剩余部分的一个因子

    考虑 P1=109+6=(5×108+3)×2P-1=10^9+6=(5\times 10^8+3)\times 2

    将组合数分为三个部分维护:22 的指数、5×108+35\times 10^8+3 的指数和剩余的部分

    作乘法的时候,前两者为相加,后者为乘积

    作除法的时候,前两者为相减,后者为乘上逆元(逆元直接取 φ(P1)=5×108+2\boldsymbol \varphi(P-1)=5\times 10^8+2 指数即可)

    查询值的时候暴力跑一下快速幂即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> pii;
    typedef double db;
    #define fi first
    #define se second
    
    const int P=1e9+7;
    inline ll fpow(ll a, ll x, ll mod) { ll ans=1; for(;x;x>>=1,a=a*a%mod) if(x&1) ans=ans*a%mod; return ans; }
    
    int p[2]={2, P>>1}, phi=p[1]-1;
    struct exnum{
        int x, cnt[2];
        exnum() { x=0; cnt[0]=cnt[1]=0; }
        exnum(int val_) {
            cnt[0]=cnt[1]=0;
            for(int i=0; i<2; ++i)
                while(val_%p[i]==0)
                    ++cnt[i], val_/=p[i];
            x=val_;
        }
        exnum(int x_, int c0_, int c1_):x(x_) { cnt[0]=c0_; cnt[1]=c1_; }
        inline int val() const { return fpow(p[0], cnt[0], P-1)*fpow(p[1], cnt[1], P-1)%(P-1)*x%(P-1); }
    };
    inline exnum operator * (const exnum &a, const exnum &b) { return exnum((ll)a.x*b.x%(P-1), a.cnt[0]+b.cnt[0], a.cnt[1]+b.cnt[1]); }
    inline exnum operator / (const exnum &a, const exnum &b) { return exnum((ll)a.x*fpow(b.x, phi-1, P-1)%(P-1), a.cnt[0]-b.cnt[0], a.cnt[1]-b.cnt[1]); }
    inline exnum operator * (const exnum &a, int b) { return a*exnum(b); }
    inline exnum operator / (const exnum &a, int b) { return a/exnum(b); }
    
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0); cout.tie(0);
        int n, res=1;
        cin>>n;
        exnum comb(1);
        for(int i=1, a; i<=n; ++i) {
            cin>>a;
            res=(ll)res*fpow(a, comb.val(), P)%P;
            if(i<n) comb=comb*(n-i)/i;
        }
        cout<<res;
        cout.flush();
        return 0;
    }
    
    • @ 2023-7-1 21:54:37

      我还不太会

  • 1
    @ 2023-10-14 8:54:34
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> pii;
    typedef double db;
    #define fi first
    #define se second
    
    const int P=1e9+7;
    inline ll fpow(ll a, ll x, ll mod) { ll ans=1; for(;x;x>>=1,a=a*a%mod) if(x&1) ans=ans*a%mod; return ans; }
    
    int p[2]={2, P>>1}, phi=p[1]-1;
    struct exnum{
        int x, cnt[2];
        exnum() { x=0; cnt[0]=cnt[1]=0; }
        exnum(int val_) {
            cnt[0]=cnt[1]=0;
            for(int i=0; i<2; ++i)
                while(val_%p[i]==0)
                    ++cnt[i], val_/=p[i];
            x=val_;
        }
        exnum(int x_, int c0_, int c1_):x(x_) { cnt[0]=c0_; cnt[1]=c1_; }
        inline int val() const { return fpow(p[0], cnt[0], P-1)*fpow(p[1], cnt[1], P-1)%(P-1)*x%(P-1); }
    };
    inline exnum operator * (const exnum &a, const exnum &b) { return exnum((ll)a.x*b.x%(P-1), a.cnt[0]+b.cnt[0], a.cnt[1]+b.cnt[1]); }
    inline exnum operator / (const exnum &a, const exnum &b) { return exnum((ll)a.x*fpow(b.x, phi-1, P-1)%(P-1), a.cnt[0]-b.cnt[0], a.cnt[1]-b.cnt[1]); }
    inline exnum operator * (const exnum &a, int b) { return a*exnum(b); }
    inline exnum operator / (const exnum &a, int b) { return a/exnum(b); }
    
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0); cout.tie(0);
        int n, res=1;
        cin>>n;
        exnum comb(1);
        for(int i=1, a; i<=n; ++i) {
            cin>>a;
            res=(ll)res*fpow(a, comb.val(), P)%P;
            if(i<n) comb=comb*(n-i)/i;
        }
        cout<<res;
        cout.flush();
        return 0;
    }
    
    
    • 0
      @ 2024-3-8 19:06:52
      #include<bits/stdc++.h>
      using namespace std;
      typedef long long ll;
      typedef pair<ll, ll> pii;
      typedef double db;
      #define fi first
      #define se second
      
      const int P=1e9+7;
      inline ll fpow(ll a, ll x, ll mod) { ll ans=1; for(;x;x>>=1,a=a*a%mod) if(x&1) ans=ans*a%mod; return ans; }
      
      int p[2]={2, P>>1}, phi=p[1]-1;
      struct exnum{
          int x, cnt[2];
          exnum() { x=0; cnt[0]=cnt[1]=0; }
          exnum(int val_) {
              cnt[0]=cnt[1]=0;
              for(int i=0; i<2; ++i)
                  while(val_%p[i]==0)
                      ++cnt[i], val_/=p[i];
              x=val_;
          }
          exnum(int x_, int c0_, int c1_):x(x_) { cnt[0]=c0_; cnt[1]=c1_; }
          inline int val() const { return fpow(p[0], cnt[0], P-1)*fpow(p[1], cnt[1], P-1)%(P-1)*x%(P-1); }
      };
      inline exnum operator * (const exnum &a, const exnum &b) { return exnum((ll)a.x*b.x%(P-1), a.cnt[0]+b.cnt[0], a.cnt[1]+b.cnt[1]); }
      inline exnum operator / (const exnum &a, const exnum &b) { return exnum((ll)a.x*fpow(b.x, phi-1, P-1)%(P-1), a.cnt[0]-b.cnt[0], a.cnt[1]-b.cnt[1]); }
      inline exnum operator * (const exnum &a, int b) { return a*exnum(b); }
      inline exnum operator / (const exnum &a, int b) { return a/exnum(b); }
      
      int main(){
          ios::sync_with_stdio(0);
          cin.tie(0); cout.tie(0);
          int n, res=1;
          cin>>n;
          exnum comb(1);
          for(int i=1, a; i<=n; ++i) {
              cin>>a;
              res=(ll)res*fpow(a, comb.val(), P)%P;
              if(i<n) comb=comb*(n-i)/i;
          }
          cout<<res;
          cout.flush();
          return 0;
      }
      
      
      • 0
        @ 2023-11-1 20:19:24
        #include<bits/stdc++.h>
        using namespace std;
        typedef long long ll;
        typedef pair<ll, ll> pii;
        typedef double db;
        #define fi first
        #define se second
        
        const int P=1e9+7;
        inline ll fpow(ll a, ll x, ll mod) { ll ans=1; for(;x;x>>=1,a=a*a%mod) if(x&1) ans=ans*a%mod; return ans; }
        
        int p[2]={2, P>>1}, phi=p[1]-1;
        struct exnum{
            int x, cnt[2];
            exnum() { x=0; cnt[0]=cnt[1]=0; }
            exnum(int val_) {
                cnt[0]=cnt[1]=0;
                for(int i=0; i<2; ++i)
                    while(val_%p[i]==0)
                        ++cnt[i], val_/=p[i];
                x=val_;
            }
            exnum(int x_, int c0_, int c1_):x(x_) { cnt[0]=c0_; cnt[1]=c1_; }
            inline int val() const { return fpow(p[0], cnt[0], P-1)*fpow(p[1], cnt[1], P-1)%(P-1)*x%(P-1); }
        };
        inline exnum operator * (const exnum &a, const exnum &b) { return exnum((ll)a.x*b.x%(P-1), a.cnt[0]+b.cnt[0], a.cnt[1]+b.cnt[1]); }
        inline exnum operator / (const exnum &a, const exnum &b) { return exnum((ll)a.x*fpow(b.x, phi-1, P-1)%(P-1), a.cnt[0]-b.cnt[0], a.cnt[1]-b.cnt[1]); }
        inline exnum operator * (const exnum &a, int b) { return a*exnum(b); }
        inline exnum operator / (const exnum &a, int b) { return a/exnum(b); }
        
        int main(){
            ios::sync_with_stdio(0);
            cin.tie(0); cout.tie(0);
            int n, res=1;
            cin>>n;
            exnum comb(1);
            for(int i=1, a; i<=n; ++i) {
                cin>>a;
                res=(ll)res*fpow(a, comb.val(), P)%P;
                if(i<n) comb=comb*(n-i)/i;
            }
            cout<<res;
            cout.flush();
            return 0;
        }
        
        • 0
          @ 2023-3-25 17:34:23
          #include<bits/stdc++.h>
          using namespace std;
          typedef long long ll;
          typedef pair<ll, ll> pii;
          typedef double db;
          #define fi first
          #define se second
          
          const int P=1e9+7;
          inline ll fpow(ll a, ll x, ll mod) { ll ans=1; for(;x;x>>=1,a=a*a%mod) if(x&1) ans=ans*a%mod; return ans; }
          
          int p[2]={2, P>>1}, phi=p[1]-1;
          struct exnum{
              int x, cnt[2];
              exnum() { x=0; cnt[0]=cnt[1]=0; }
              exnum(int val_) {
                  cnt[0]=cnt[1]=0;
                  for(int i=0; i<2; ++i)
                      while(val_%p[i]==0)
                          ++cnt[i], val_/=p[i];
                  x=val_;
              }
              exnum(int x_, int c0_, int c1_):x(x_) { cnt[0]=c0_; cnt[1]=c1_; }
              inline int val() const { return fpow(p[0], cnt[0], P-1)*fpow(p[1], cnt[1], P-1)%(P-1)*x%(P-1); }
          };
          inline exnum operator * (const exnum &a, const exnum &b) { return exnum((ll)a.x*b.x%(P-1), a.cnt[0]+b.cnt[0], a.cnt[1]+b.cnt[1]); }
          inline exnum operator / (const exnum &a, const exnum &b) { return exnum((ll)a.x*fpow(b.x, phi-1, P-1)%(P-1), a.cnt[0]-b.cnt[0], a.cnt[1]-b.cnt[1]); }
          inline exnum operator * (const exnum &a, int b) { return a*exnum(b); }
          inline exnum operator / (const exnum &a, int b) { return a/exnum(b); }
          
          int main(){
              ios::sync_with_stdio(0);
              cin.tie(0); cout.tie(0);
              int n, res=1;
              cin>>n;
              exnum comb(1);
              for(int i=1, a; i<=n; ++i) {
                  cin>>a;
                  res=(ll)res*fpow(a, comb.val(), P)%P;
                  if(i<n) comb=comb*(n-i)/i;
              }
              cout<<res;
              cout.flush();
              return 0;
          }
          
          
          • 1

          信息

          ID
          87
          时间
          1000ms
          内存
          256MiB
          难度
          5
          标签
          递交数
          79
          已通过
          28
          上传者