題目鏈接:Matrix from Arrays
題意
給定一個長度爲 的數組 ,用以下代碼生成一個無窮大矩陣:
int cursor = 0;
for (int i = 0; ; ++i) {
for (int j = 0; j <= i; ++j) {
M[j][i - j] = A[cursor];
cursor = (cursor + 1) % L;
}
}
有 次詢問,每次詢問爲從第 行 列到第 行 列的子矩陣中數字的和。
輸入
第一行爲一個整數 ,接下有 組數據,每組數據第一行爲一個整數 ,第二行爲 個整數 ,第三行爲一個整數 ,接下去 行每行四個整數 。
輸出
對於每次詢問,輸出結果。
樣例
輸入 |
---|
1 3 1 10 100 5 3 3 3 3 2 3 3 3 2 3 5 8 5 1 10 10 9 99 999 1000 |
輸出 |
1 101 1068 2238 33076541 |
題解
打表可以發現矩陣的循環節爲 ,因此可以只打出 的矩陣,就可以通過循環節求出所有矩陣的值,設 爲無窮大矩陣前 行 列的和,則所求子矩陣的和爲
注意 取得 的情況。
過題代碼
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <sstream>
using namespace std;
#define LL long long
const int maxn = 100 + 100;
int T, n, q;
int a[maxn];
LL num[maxn][maxn];
LL Sum(int x, int y) {
if(x < 0 || y < 0) {
return 0;
}
int nn = n << 1;
LL ret = num[nn - 1][nn - 1] * ((x + 1) / nn) * ((y + 1) / nn);
int xx = x % nn;
int yy = y % nn;
if(xx != nn - 1) {
ret += num[xx][nn - 1] * ((y + 1) / nn);
}
if(yy != nn - 1) {
ret += num[nn - 1][yy] * ((x + 1) / nn);
}
if(xx != nn - 1 && yy != nn - 1) {
ret += num[xx][yy];
}
return ret;
}
int main() {
#ifdef Dmaxiya
freopen("test.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // Dmaxiya
ios::sync_with_stdio(false);
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = 0; i < n; ++i) {
scanf("%d", &a[i]);
}
int Index = 0;
for(int i = 0; i < maxn; ++i) {
for(int j = 0; j <= i; ++j) {
num[j][i - j] = a[Index];
Index = (Index + 1) % n;
}
}
for(int i = 0; i < maxn; ++i) {
for(int j = 0; j < maxn; ++j) {
if(i != 0) {
num[i][j] += num[i - 1][j];
}
if(j != 0) {
num[i][j] += num[i][j - 1];
}
if(i != 0 && j != 0) {
num[i][j] -= num[i - 1][j - 1];
}
}
}
scanf("%d", &q);
int x1, x2, y1, y2;
while(q--) {
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
LL ans = Sum(x2, y2) + Sum(x1 - 1, y1 - 1);
ans -= Sum(x2, y1 - 1) + Sum(x1 - 1, y2);
printf("%I64d\n", ans);
}
}
return 0;
}