zoukankan      html  css  js  c++  java
  • FZU 1692 Key problem

    FZU_1692

        首先感觉输入数据里面的L和R应该反过来读取即先读入R再读入L,要不然样例算不出来,不知道是不是我理解错题意了。

        矩阵不难构造,但这个题让进一步注意到了矩阵运算中的常熟优化:

        ①由于递推关系的矩阵各行是循环同构的,而两个这样的循环同构的矩阵的乘积依然是循环同构的,所以在用二分矩阵的方法计算的时候,可以先用O(N^2)的时间计算出第一行,再用O(N^2)的时间平移出下面各行的结果,这样每次做乘法的复杂度就由O(N^3)减少到了O(N^2)。

        ②矩阵乘法的multiply的函数最好使用引用传递传参,如果直接传参的话每次相当于把矩阵复制一遍,这样效率就比较低了。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 110
    int N, M, L, R, D, a[MAXD];
    struct Matrix
    {
        int a[MAXD][MAXD];
        Matrix()
        {
            memset(a, 0, sizeof(a));
        }
        void init()
        {
            int i, j;
            for(i = 0; i < N; i ++)
                a[i][(i + N - 1) % N] = L, a[i][i] = 1, a[i][(i + 1) % N] = R;
        }
    };
    Matrix multiply(Matrix &x, Matrix &y)
    {
        int i, j, k;
        Matrix z;
        for(k = 0; k < N; k ++)
            if(x.a[0][k])
            {
                for(j = 0; j < N; j ++)
                    if(y.a[k][j])
                z.a[0][j] = (z.a[0][j] + (long long)x.a[0][k] * y.a[k][j]) % D;
            }
        for(i = 1; i < N; i ++)
        {
            z.a[i][0] = z.a[i - 1][N - 1];
            for(j = 1; j < N; j ++)
                z.a[i][j] = z.a[i - 1][j - 1];
        }
        return z;
    }
    Matrix powmod(Matrix unit, Matrix mat, int n)
    {
        while(n)
        {
            if(n & 1)
                unit = multiply(mat, unit);
            n >>= 1;
            mat = multiply(mat, mat);
        }
        return unit;
    }
    void solve()
    {
        int i, j, ans;
        Matrix unit, mat;
        scanf("%d%d%d%d%d", &N, &M, &R, &L, &D);
        for(i = 0; i < N; i ++)
        {
            scanf("%d", &a[i]);
            unit.a[i][i] = 1;
        }
        mat.init();
        unit = powmod(unit, mat, M);
        for(i = 0; i < N; i ++)
        {
            ans = 0;
            for(j = 0; j < N; j ++)
                if(unit.a[i][j] && a[j])
                    ans = (ans + (long long)unit.a[i][j] * a[j]) % D;
            if(i)
                printf(" ");
            printf("%d", ans);
        }
        printf("\n");
    }
    int main()
    {
        int t;
        scanf("%d", &t);
        while(t --)
        {
            solve();
        }
        return 0;
    }
  • 相关阅读:
    【Linux】VMware及VirtualBox网络配置
    【Linux】VirtualBox安装ubuntu排错LowGraphic
    【Hadoop】Win7上搭建Hadoop开发环境,方法一
    【JAVA】配置JAVA环境变量,安装Eclipse
    Eureka自我保护机制
    zookeeper代替eureka作为SpringCloud的服务注册中心
    mybatisplus代码生成器
    条件构造器 EntityWrapper (重要)
    idea 常用快捷键
    MybatisPlus的通用 CRUD
  • 原文地址:https://www.cnblogs.com/staginner/p/2471017.html
Copyright © 2011-2022 走看看