1. 程式人生 > 實用技巧 >Problem B 矩陣

Problem B 矩陣

Problem Description

給定兩個n階方陣A和B,矩陣C=A * B,現在有q個詢問,每次詢問修改矩陣A或矩陣B的一個元素,請求出每次修改後矩陣C的主對角線元素之和。

Input

多組測試資料,每組測試資料中:

第一行輸入兩個整數n和q,分別表示方陣大小和詢問個數。

接下來2*n行每行n個整數,分別描述矩陣A和矩陣B。

再下面q行,每行4個整數ki,xi,yi,vi表示詢問。若ki= 0 表示要修改的是矩陣A,若ki= 1表示要修改的是矩陣B。將要修改的矩陣的第xi行,第yi列的元素修改為vi

n <= 1000,q <= 10^6,vi<= 1000,矩陣A和B初始元素<=1000。

Output

對於每組測試資料:

輸出q行,每行一個整數,表示修改後矩陣C的主對角線元素之和。

Sample Input

2 2 1 1 1 1 1 1 1 1 0 2 2 2 1 2 2 2

Sample Output

5 7
#include <iostream>

using namespace std;

typedef long long ll;

const int N = 1010;

ll n, q;
ll a[N][N], b[N][N];
ll res, ans;

int main(){
    while (~scanf("%lld%lld", &n, &q)){
    res = 0, ans = 0;
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= n; j ++ )
            scanf("%lld", &a[i][j]);
    
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= n; j ++ )
            scanf("%lld", &b[i][j]);
    
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= n; j ++ )
            res += a[i][j] * b[j][i];
            
    while (q -- ){
        ll k, x, y, v;
        scanf("%lld%lld%lld%lld", &k, &x, &y, &v);
        if (!k){//修改A矩陣
            ll t = a[x][y] * b[y][x];//原來座標下的值
            ll u = v * b[y][x];//現在座標下的值
            a[x][y] = v;//修改矩陣
            ans = ans - t + u;
            printf("%lld\n", res + ans);
        }
        if (k) {//修改B矩陣
            ll t = a[y][x] * b[x][y];//原來座標下的值
            ll u = a[y][x] * v;//現在座標下的值
            b[x][y] = v;//修改矩陣
            ans = ans - t + u;
            printf("%lld\n", res + ans);
        }
    }
    }
    
    return 0;
}