zoukankan      html  css  js  c++  java
  • 矩阵游戏(game)

    矩阵游戏(game)

    ——九校联考24OI__D1T1

    问题描述

    LZK发明一个矩阵游戏,大家一起来玩玩吧,有一个N行M列的矩阵。第一行的数字是1,2,…M,第二行的数字是M+1,M+2…2*M,以此类推,第N行的数字是(N-1)*M+1,(N-1)*M+2…N*M。
    例如,N=3,M=4的矩阵是这样的:
    1 2 3 4
    5 6 7 8
    9 10 11 12

    对于身为智慧之神的LZK来说,这个矩阵过于无趣.于是他决定改造这个矩阵,改造会进行K次,每次改造会将矩阵的某一行或某一列乘上一个数字,你的任务是计算最终这个矩阵内所有数字的和,输出答案对109+7取模。

    输入

    第一行包含三个正整数N、M、K,表示矩阵的大小与改造次数。接下来的行,每行会是如下两种形式之一:
    R X Y,表示将矩阵的第X(1 ≤ X ≤ N)行变为原来的Y((0) ≤ Y ≤(10^9))倍.
    S X Y,表示将矩阵的第X(1 ≤ X ≤ M)列变为原来的Y((0) ≤ Y ≤(10^9))倍.

    输出

    输出一行一个整数,表示最终矩阵内所有元素的和对(10^9+7)取模的结果。

    输入输出样例

    样例1

    input
    3 4 4
    R 2 4
    S 4 1
    R 3 2
    R 2 0
    output
    94

    样例2

    input
    2 4 4
    S 2 0
    S 2 3
    R 1 5
    S 1 3
    output
    80

    样例一的解释:操作结束之后矩阵会变成这样:
    1 2 3 4
    0 0 0 0
    18 20 22 24

    数据范围

    40%的数据满足:1≤N,M≤1000;
    80%的数据满足:1≤N,M≤1000000,1 ≤ K ≤1000;
    100%的数据满足:1≤N,M≤1000000,1 ≤ K ≤100000。

    解析

    这道题看似是什么数据结构,其实就是数学题。
    每一个行都是等差数列(列也是),求出每一行数字的和s[i]。每一次横行的乘法操作就是重构一下通项公式,每一次纵列的乘法操作就是改变每一个数列中的一项,至于每一行增加了多少,就用通项求那个数是多少,再求增加量,加到s[i]里。
    别忘了开longlong,取模,好多同学都忘了这个。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int N,M,K;
    const int MOD = (1e9) + 7;
    int R[1000005];
    int sumR;
    int C[1000005];
    int S;
    int rez;
    int element(int i,int j){
        return (1LL * (i - 1) * M + j) % MOD;
    }
    int main()
    {
    //	freopen("game.in","r",stdin);
    //	freopen("game.out","w",stdout);
        for(int i = 1;i <= 1000000;i++){
            R[i] = C[i] = 1;
        }
        cin >> N >> M >> K;
        for(int i = 1;i <= K;i++){
            char c;
            int x,y;
            cin >> c >> x >> y;
            if(c == 'R'){
                R[x] = 1LL * R[x] * y % MOD;
            }
            else {
                C[x] = 1LL * C[x] * y % MOD;
            }
        }
        for(int i = 1;i <= N;i++){
            S = (1LL * S + 1LL * element(i,1) * R[i]) % MOD;
            sumR += R[i];
            if(sumR >= MOD){
                sumR -= MOD;
            }
        }
        for(int i = 1;i <= M;i++){
            rez = (1LL * rez + 1LL * S * C[i]) % MOD;
            if(rez >= MOD){
                rez -= MOD;
            }
            S += sumR;
            if(S >= MOD){
                S -= MOD;
            }
        }
        cout << rez<<endl;
        return 0;
    }
    
  • 相关阅读:
    HDU1852 Beijing 2008(快速幂+特殊公式)
    HihoCoder 1570 : 小Hi与法阵(简单几何)
    【转】反素数
    【整理】线段树30题
    SPOJcot2 Count on a tree II (树上莫队)
    【总结】曼哈顿距离转切比雪夫距离
    【初识】树上分块
    基于Tablestore Tunnel的数据复制实战
    【New Feature】阿里云快照服务技术解析
    基于日志服务的GrowthHacking(1):数据埋点和采集(APP、Web、邮件、短信、二维码埋点技术)
  • 原文地址:https://www.cnblogs.com/Ch-someone/p/9664313.html
Copyright © 2011-2022 走看看