• 洛谷P4902乘积


    题面链接

    洛谷

    题意简述

    (prod_{i=A}^Bprod_{j=1}^i lgroup frac{i}{j} group ^{lfloor frac{i}{j} floor})

    sol

    我的做法是观察法,首先我们把(i)(j^{-1})分开做,可以看到

    (i)的是这样的。表格内是每个(i)(j)的对应(i)的贡献

    (1^1)
    (2^2) (2^1)
    (3^3) (3^1) (3^1)
    (4^4) (4^2) (4^1) (4^1)
    (5^5) (5^2) (5^1) (5^1) (5^1)
    (6^6) (6^3) (6^2) (6^1) (6^1) (6^1)

    可以发现第(i)行我们只要快速求出指数就可以快速幂了。然后会发现一个神奇的性质,第(i)列每过(i)就会让指数加(1)。这样的话我们给(i,2i,3i,4i,5i...)加1,然后前缀和就行了。

    要不还是再说清楚点吧。下面这个表是要加的指数。

    1
    1 1
    1 0 1
    1 1 0 1
    1 0 0 0 1
    1 1 1 0 0 1
    1 0 0 0 0 0 1
    1 1 0 1 0 0 0 1

    然后对每列做一遍前缀和。

    1
    2 1
    3 1 1
    4 2 1 1
    5 2 1 1 1
    6 3 2 1 1 1
    7 3 2 1 1 1 1
    8 4 2 2 1 1 1 1

    然后就变回去了,这也许是差分的思想???具体实现不需要对每列开数组,丢到一起就OK了。

    下面的1,2,3,4,5,6均指 他们的逆元

    (1^1)
    (1^2) (2^1)
    (1^3) (2^1) (3^1)
    (1^4) (2^2) (3^1) (4^1)
    (1^5) (2^2) (3^1) (4^1) (5^1)
    (1^6) (2^3) (3^2) (4^1) (5^1) (6^1)

    这是(j^{-1})的贡献。

    然后和上面一样搞,但我们直接把这个数乘上去而不是加指数。

    相信泥萌都懂了。那么我就贴个代码。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define gt getchar()
    #define ll long long
    #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    inline int in()
    {
        int k=0;char ch=gt;
        while(ch<'-')ch=gt;
        while(ch>'-')k=k*10+ch-'0',ch=gt;
        return k;
    }
    const int YL=19260817,N=2e6+5,M=1e6;
    inline int ksm(int a,int k){int r=1;while(k){if(k&1)r=1ll*r*a%YL;a=1ll*a*a%YL,k>>=1;}return r;}
    inline int MO(const int &a){return a>=YL?a-YL:a;}
    int sum[N],sum_i[N],inv[N];
    int main()
    {
        sum_i[0]=1;
        for(int i=1;i<=M;++i)inv[i]=ksm(i,YL-2);
        for(int i=1;i<=M;++i)
            for(int j=i;j<=M;j+=i)++sum[j];
        for(int i=1;i<=M;++i)sum[i]=(sum[i]+sum[i-1])%(YL-1);
        for(int i=1;i<=M;++i)sum_i[i]=1ll*ksm(i,sum[i])*sum_i[i-1]%YL;
        for(int i=1;i<=M;++i)sum[i]=1;
        for(int i=1;i<=M;++i)
            for(int j=i;j<=M;j+=i)sum[j]=1ll*sum[j]*inv[i]%YL;
        for(int i=2;i<=M;++i)sum[i]=1ll*sum[i]*sum[i-1]%YL;
        for(int i=2;i<=M;++i)sum[i]=1ll*sum[i]*sum[i-1]%YL;
        for(int i=1;i<=M;++i)sum[i]=1ll*sum[i]*sum_i[i]%YL;
        sum[0]=1;
        int t=in();
        while(t--)
        {
            int a=in(),b=in();
            printf("%lld
    ",1ll*sum[b]*ksm(sum[a-1],YL-2)%YL);
        }
        return 0;
    }
    
  • 相关阅读:
    POJ2686 Traveling by Stagecoach(状压DP+SPFA)
    POJ3250 Bad Hair Day(单调栈)
    POJ3493 Largest Submatrix of All 1’s(单调栈)
    UVA 10160 Servicing Stations(状态压缩+迭代加深)
    POJ 2187 Beauty Contest
    HDU 6017 Girls Love 233(多态继承DP)
    POJ 2932 Coneology(扫描线)
    POJ 1127 Jack Straws (计算几何)
    挑战程序设计竞赛 3.5 借助水流解决问题的网络流
    AOJ 2230 How to Create a Good Game(费用流)
  • 原文地址:https://www.cnblogs.com/cx233666/p/9736923.html
Copyright © 2020-2023  润新知