zoukankan      html  css  js  c++  java
  • NOIP 模拟 $86; m 乘法$

    题解 (by;zjvarphi)

    先提出来所有偶数的 (2),那么所有的偶数就会变成一段从 (1) 开始的前缀和,继续递归下去计算.

    问题转化成求 (Pi_{i=1}^{(n-1)/2}(2i+1))

    将括号拆开,最多选 63 个 2,再多就会因为自然溢出而没有作用。

    所以这里可以化为:从 (n) 个数里选 (m) 个数的所有方案数的乘积和。

    (g_{n,m}) 表示从 (n) 个数中选 (m) 个,所有方案数的乘积总和,这样式子可以转化为:(sum_{i=0}^{63}g_{n,i}*2^i)

    (g) 时可以递推:(g_{n,m}=n imes g_{n-1,m-1}+g_{n-1,m})

    转化一下,(g) 表示没选的数的乘积:(g_{n,m}=g_{n-1,m-1}+n imes g_{n-1,m})

    发现给 (n)(1) 后就变成了第一类斯特林数 (n+1 rack n-m+1)

    这个数很大,但是发现 (n-m+1) 很小,所以圆排列中大于 (1) 的环很少。

    预处理出 (dp_{i,j}) 表示 (i) 个数分成 (j) 个圆排列,每个圆排列至少大于 (1) 的方案数。

    最后就是如何求逆元,发现偶数无法求逆元,所以将偶数除去所有 (2) 的因子,剩下的奇数利用欧拉定理求出即可。

    Code
    #include<bits/stdc++.h>
    #define ri signed
    #define pd(i) ++i
    #define bq(i) --i
    #define func(x) std::function<x>
    namespace IO{
        char buf[1<<21],*p1=buf,*p2=buf;
        #define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?(-1):*p1++
        #define debug1(x) std::cerr << #x"=" << x << ' '
        #define debug2(x) std::cerr << #x"=" << x << std::endl
        #define Debug(x) assert(x)
        struct nanfeng_stream{
            template<typename T>inline nanfeng_stream &operator>>(T &x) {
                bool f=false;x=0;char ch=gc();
                while(!isdigit(ch)) f|=ch=='-',ch=gc();
                while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=gc();
                return x=f?-x:x,*this;
            }
        }cin;
    }
    using IO::cin;
    namespace nanfeng{
        #define FI FILE *IN
        #define FO FILE *OUT
        template<typename T>inline T cmax(T x,T y) {return x>y?x:y;}
        template<typename T>inline T cmin(T x,T y) {return x>y?y:x;}
        using ull=unsigned long long;
        static const int N=155;
        int T;
        ull A[N][N],dp[N][N],inv[N];
        auto fpow=[](ull x,ull y) {
            ull res=1ull;
            while(y) {
                if (y&1) res=res*x;
                x=x*x;
                y>>=1; 
            }
            return res;
        };
        auto C=[](ull n,int m) {
            ull res=1ull;
            int cnt=0;
            for (ri i(1);i<=m;pd(i)) {
                res*=inv[i];
                int k=i;
                while(!(k&1)) k>>=1,++cnt;
            }
            for (ull i(n-m+1);i<=n;pd(i)) {
                ull k=i;
                while(cnt&&!(k&1)) k>>=1,--cnt;
                res*=k;
            }
            return res;
        };
        auto calc=[](ull x) {
            --x;
            x>>=1;
            ull res=0;
            ++x;
            for (ri t(0);t<64&&t<x;pd(t)) {
                ull tmp=0;
                for (ri k(t);k<=t<<1&&k<=x;pd(k)) tmp+=C(x,k)*dp[k][k-t];
                res+=tmp<<t;
            }
            return res;
        };
        inline int main() {
            FI=freopen("multiplication.in","r",stdin);
            FO=freopen("multiplication.out","w",stdout);
            for (ri i(0);i<=N-5;pd(i)) {
                A[i][0]=1ull;
                for (ri j(1);j<=i;pd(j)) A[i][j]=A[i][j-1]*(i-j+1);
            }
            dp[0][0]=1ull;
            for (ri i(1);i<=N-5;pd(i))
                for (ri j(1);j<=i;pd(j))
                    for (ri k(2);k<=i;pd(k)) dp[i][j]+=A[i-1][k-1]*dp[i-k][j-1];
            for (ri i(1);i<=150;pd(i)) {
                ull x=i;
                while(!(x&1)) x>>=1;
                inv[i]=fpow(x,(1ull<<63)-1ull);
            }
            cin >> T;
            for (ri i(1);i<=T;pd(i)) {
                ull x,c=0,ans=1ull;
                cin >> x;
                while(x) ans*=calc(x),x>>=1,c+=x;
                ans<<=(c%4);
                bool jud=false;
                for (ri t(15);~t;bq(t)) {
                    ull tmp=ans>>(t*4)&15;
                    if (tmp) jud=true;
                    if (jud) putchar(tmp<10?tmp+'0':tmp-10+'A');
                }
                printf("
    ");
            }
            return 0;
        }
    }
    int main() {return nanfeng::main();}
    
  • 相关阅读:
    基数排序
    kt-Mapper 笔记
    归并排序
    快速排序
    第十一天——递归(五)
    第十天——闭包(一)
    第八天——函数的嵌套以及gloabal、nonlocal(三)(重点:执行过程)
    第八天——函数的作用域(二)
    第八天——函数的动态参数(一)
    第七天——函数的参数(二)
  • 原文地址:https://www.cnblogs.com/nanfeng-blog/p/15488493.html
Copyright © 2011-2022 走看看