• CodeChef Sereja and LCM(矩阵快速幂)


    Sereja and LCM

     
    Problem code: SEALCM
     

    All submissions for this problem are available.

    Read problems statements in Mandarin Chinese and Russian.

    In this problem Sereja is interested in number of arrays A[1], A[2], ..., A[N] (1 ≤ A[i] ≤ M, A[i] - integer)
    such that least common multiple (LCM) of all its elements is divisible by number D.

    Please, find sum of answers to the problem with D = L, D = L+1, ..., D = R. As answer could be large, please output it modulo
    (109 + 7).

    Input

    • First line of input contain integer T - number of test cases.
    • For each test case, only line of input contain four integers N, M, L, R.

    Output

    For each test case, output required sum modulo (109 + 7).

    Constraints

    • 1T10
    • 1N5*106
    • 1LRM1000

    Subtasks

    • Subtask #1: 1N, M10 (25 points)
    • Subtask #2: 1N, M 1000 (25 points)
    • Subtask #3: original constraints (50 points)

    Example

    Input:
    2
    5 5 1 5
    5 5 4 5
    
    Output:
    12310
    4202
    
    

    给出 N , M , L , R 。

    求 用 1~M ,组成N个数 ,它们的LCM能够整除d的序列个数 , d = L ~ R 。

    枚举d , 将d分解 ,d = p1^k1*p2^k2*....*pn^kn .

    当一个数与d有相同质因子 pi 且 它的ki 大于等于 d的ki时 ,就能够使得LCM起到作用。

    M只有1000 , 直接用二进制表示个个质因子的指数项是否大于等于d 的 ki 。

    然后弄好转移矩阵 , 直接快速幂就OK了 。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int mod = 1e9+7;
    const int N = 1010;
    int fac[20] , tot , all ;
    
    struct Matrix {
        LL v[50][50] ;
        Matrix(){ memset( v,0,sizeof v); }
        Matrix operator * ( const Matrix &a ) const {
            Matrix res ;
            for( int i = 0 ; i < all ; ++i )
                for( int k = 0 ; k < all ; ++k ) {
                    if( v[i][k] == 0 ) continue ;
                    for( int j = 0 ; j < all ; ++j ) {
                        res.v[i][j] = ( res.v[i][j] + v[i][k] * a.v[k][j] % mod )% mod;
                    }
                }
            return res;
        }
    };
    
    Matrix q_pow( Matrix a , int b ) {
        Matrix res = a ;
        b--;
        while( b ) {
            if( b&1 ) res = res * a ;
            a = a * a ;
            b >>= 1 ;
        }
        return res ;
    }
    
    void Work( int d ) {
        tot = 0 ;
        for( int i = 2 ; i * i <= d ; ++i ) {
            if( d % i == 0 ) {
                fac[tot++] = 1 ;
                while( d % i == 0 ) fac[tot-1] *= i , d /= i ;
            }
        }
        if( d > 1 ) fac[tot++] = d ;
    }
    
    int main() {
    //    freopen("in.txt","r",stdin);
        int _ ; cin >> _ ;
        while( _-- ) {
            int n , m , l , r ;
            LL ans = 0 ;
            cin >> n >> m >> l >> r ;
            for( int d = l ; d <= r ; ++d ) {
                Work(d);  Matrix a ;
                all = 1<<tot ;
                for( int i = 0 ; i < all ; ++i ) {
                    for( int j = 1 ; j <= m ; ++j ) {
                        int st = i ;
                        for( int k = 0 ; k < tot ; ++k ) {
                            if( j % fac[k] == 0 ) st |= (1<<k) ;
                        }
                        a.v[i][st]++;
                    }
                }
                a = q_pow(a,n);
                ans = ( ans + a.v[0][all-1] ) % mod ;
            }
            cout << ans << endl ;
        }
    }
    View Code
  • 相关阅读:
    AMD64 Instruction-Level Debugging With dbx
    Solaris 10上安装Oracle 11g
    Dave-oracle
    SSD 下的 MySQL IO 优化
    vmware 网络工作方式
    PLSQL Developer 配置Oralce11g连接 转
    LINUX下的21个特殊符号 转
    linux 内核调试相关资料
    mysql 源代码编绎
    Windows Performance Toolkit
  • 原文地址:https://www.cnblogs.com/hlmark/p/4296950.html
Copyright © 2020-2023  润新知