Automobil

本文介绍了一个关于矩阵操作的问题,通过多次行或列的乘法操作后,如何高效地计算矩阵中所有元素的总和,并给出了一种算法实现方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

Mirko has found a matrix with ​N rows and ​M columns at the back seat of his car. The first row of the matrix consists of numbers 1, 2, … ​M , the second row of numbers ​M +1, ​M ​ +2, … 2⋅​M and so on until the ​Nth row which consists of numbers (​N -1)⋅​M + 1, (​N -1)⋅​M + 2, …< N ⋅​M ​ , respectively. For example, for ​N = 3 and ​M = 4:
1 2 3 4
5 6 7 8
9 10 11 12
Such matrix wasn’t interesting enough to him, so he chose a row or a column ​K times and multiplied its values with a non-negative integer. Naturally, now he wants to know the sum of all the values from the matrix. Since this sum can be very large, Mirko will be satisfied with the value modulo 10​ 9 + 7. Help Mirko answer this question.

Input

The first line of input contains the numbers ​N (1 ≤ ​N ≤ 1 000 000), ​M (1 ≤ ​M ≤ 1 000 000) and ​K (1 ≤ ​K ≤ 1000) from the task. Each of the following ​K lines describes: ● Either the multiplication of the ​X th row with ​Y , in the form of “R ​X ​Y ​ “, where “R” represents row multiplication, ​X is a positive integer (1 ≤ ​X ≤ N), and ​Y is a non-negative integer (0 ≤ ​Y ≤ 10​9​ ).
● Or the multiplication of the ​X th column with ​Y , in the form of “S ​X ​Y ”, where “S” represents column multiplication, ​X is a positive integer (1 ≤ ​X ≤ ​M ), and ​Y is a non-negative integer (0 ≤ ​Y ​ ≤ 10​9​ ).

Output

You must output the sum of the final values from the matrix modulo 10​9​ + 7

Sample Input

3 4 4
R 2 4
S 4 1
R 3 2
R 2 0
3 1 1
S 1 4
2 4 4
S 2 0
S 2 3
R 1 5
S 1 3
Sample Output

94
24
80
题意:n行m列的表格初始数字为1,2,3,4,5,……,接下来k次操作,“R X Y”表示把第X行乘Y倍,“S X Y”表示把X列乘Y倍,求经过k次操作后整个表格所有数加起来的和是多少
思路:设r[i],c[i]分别记录每行和每列最终乘的倍数,s1,s2分别表示r[i],c[i]的和。每个数 a[i][j](其中i从0~n,j 0~m)=(i*m+j+j),将a[i][j]拆成三部分计算,即i*m、j、1三部分。
①第一部分(”1”)的计算:对每个a[i][j]来说最终会变成a[i][j]r[i]*c[j],也就是说把所有数字都看成是1时,ans=r[1]+r[2]+r[3]……)(c[1]+c[2]+c[3]+……) =s1*s2。②第二部分(i*m)的计算:对某一行i的所有数字来说,都有相同一部分,即i*m,并且每个数字都要乘上相同的倍数r[i],对于第j列的数字还要再乘上c[j],即这部分和为(i*m*r[i])(c[1]+c[2]+c[3]+……)=(i*m*r[i])s2。③第三部分(j)的计算:同一列(如j列)的数字除去之前计算过的部分,都还缺少一个j,并且每个数字都要乘上该列要乘的数c[j],并且对于不同行的数要分别乘上r[1],r[2],r[3]……即这部分和为j*c[j](r[1]+r[2]+r[3]+……) =j*c[j]*s1

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<set>
#define mod 1000000007
using namespace std;
typedef long long ll;
ll r[1000005],c[1000005];
ll s1,s2;
int n,m,k;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>k;
    for(int i=0;i<n;i++)
    r[i]=1LL;
    for(int i=0;i<m;i++)
    c[i]=1LL;
    while(k--)
    {
        char op[5];
        int x,y;
        cin>>op>>x>>y;
        if(op[0]=='R')
        r[x-1]=(r[x-1]*y)%mod;
        else
        c[x-1]=(c[x-1]*y)%mod;
    }
    ll ans=1;
    for(int i=0;i<n;i++)
    s1=(s1+r[i])%mod;
    for(int j=0;j<m;j++)
    s2=(s2+c[j])%mod;
    ans=(1LL*s1*s2)%mod;//(r[1]+r[2]+r[3]……)*(c[1]+c[2]+c[3]+……) 
    for(int i=0;i<n;i++)//(i*m*r[i]*)*(c[1]+c[2]+c[3]+……) 
    {
        ll t=(1LL*i*m)%mod;
        t=(t*r[i])%mod;
        t=(t*s2)%mod;
        ans=(ans+t)%mod;
    } 
    for(int j=0;j<m;j++)//j*c[j]*(r[1]+r[2]+r[3]+……) 
    {
        ll t=(1LL*j)%mod;
        t=(t*c[j])%mod;
        t=(t*s1)%mod;
        ans=(ans+t)%mod;
    }
    cout<<ans<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值