2012-10-25 08:38:14Morris

[ZJ][逆元] a545. Stressful

內容 :

在 這充滿學測考生的圖書館中,每個人都感受到莫大的壓力,但由於每個人的實力值不同,所以感受到的壓力值也不同,因此便有一種量化壓力值的算法,來求得每一 位考生所感受到的壓力,這種算法便是除了自己以外的實力值通通相乘起來,便能得到該名考生在圖書館中所感受到的壓力值。但對於準備學測的考生來說,沒有辦 法花時間來一一計算自己的壓力值,因此,你被要求編寫一段程式來求得每位考生所感受到的壓力值為何。

此處該圖書館為一矩陣,且由於準備學測的考生眾多,並沒有任何位置被空置下來。

輸入說明 :

輸入第一行包含兩正整數m,n(0<m,n<=103)。

接下來m行,每行有n個正整數Vij,代表該位置上考生的實力值。 

接下來一行包含一個正整數q(0<q<=104),代表接下來會有q筆詢問。

接下來q行各包含兩個正整數x,y(0<x<=m,0,<y<=n)。

測試資料以兩個零代表輸入結束。 

任何數據皆能以long long(64 bits)儲存。

輸出說明 :

對於每一筆詢問求出在位置(x,y)的考生所感受到的壓力值,由於壓力值可能非常大請輸出該名考生壓力值對於 100000007 的餘數即可。

範例輸入 :

2 3
1 2 3
4 5 6
1
1 2
0 0

範例輸出 :

360

提示 :

背景知識:

 範例測資如下

Index

1

2

3

1

1

2    

3

2

4

5

6

 詢問的考生如◎標記處,則其壓力值為其餘所有考生實力值相乘(1*3*4*5*6),即為範例輸出之360。

出處 :

(管理:eddy841021)
除一個數字,相當於乘上他的乘法反元素。
這題一定要優化輸入。
逆元的求法可以使用費馬小定理 (因為 1,0000,0007 是個質數)。
或者使用 gcd 的方法。


#include <stdio.h>
#include <stdlib.h>
#define mod 100000007LL
#define LL long long
int A[1005][1005];
LL inv(LL a) {
    LL d = mod, x = 0, s = 1, q, r, t;
    while(a) {
        q = d / a, r = d % a;
        d = a, a = r;
        t = x - q * s, x = s, s = t;
    }
    if (d != 1) return -1;
    return (x + mod) % mod;
}
inline int ReadInt(int *x) {
    static char c, neg;
    while((c = getchar()) < '-')    {if(c == EOF) return EOF;}
    neg = (c == '-') ? -1 : 1;
    *x = (neg == 1) ? c-'0' : 0;
    while((c = getchar()) >= '0')
        *x = (*x << 3) + (*x << 1) + c-'0';
    *x *= neg;
    return 1;
}
int main() {
    int n, m, q, i, j;
    while(scanf("%d %d", &n, &m) == 2) {
        if(n == 0)  break;
        LL tot = 1, tmp;
        for(i = 0; i < n; i++) {
            for(j = 0; j < m; j++) {
                ReadInt(&A[i][j]);
                if(A[i][j] >= mod)
                    A[i][j] %= mod;
                tot *= A[i][j];
                if(tot >= mod)
                    tot %= mod;
            }
        }
        tot = (tot+mod)%mod;
        scanf("%d", &q);
        while(q--) {
            scanf("%d %d", &i, &j), i--, j--;
            tmp = inv(A[i][j])*tot;
            if(tmp >= mod)
                tmp %= mod;
            printf("%lld\n", tmp);
        }
    }
    return 0;
}