题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6336
题目:
题意:给你一个l个元素的数组a,用题目中的程序构造一个新的矩阵,询问q次,问以(x1,y1)为左上角,(x2,y2)为右下角的矩阵内的元素之和(原点在左上角)。
思路:我们通过打表可以发现这个大矩阵都是以左上角2l*2l的小矩阵M循环出现的,所以对于每次查询我们只需统计他要查询的矩阵包含多少个完整的M,对于那些不构成完整的行列和,我们首先用前缀和统计出来,最后加起来即可。我的方法用下图表示,答案就是S1-S2-S3+S4(S4为左上角那个小正方形):
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <queue> 4 #include <stack> 5 #include <cmath> 6 #include <bitset> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 16 typedef long long ll; 17 typedef pair<ll, ll> pll; 18 typedef pair<ll, int> pli; 19 typedef pair<int, ll> pil;; 20 typedef pair<int, int> pii; 21 typedef unsigned long long ull; 22 23 #define lson i<<1 24 #define rson i<<1|1 25 #define bug printf("*********\n"); 26 #define FIN freopen("D://code//in.txt", "r", stdin); 27 #define debug(x) cout<<"["<<x<<"]" <<endl; 28 #define IO ios::sync_with_stdio(false),cin.tie(0); 29 30 const double eps = 1e-8; 31 const int mod = 10007; 32 const int maxn = 1e6 + 7; 33 const double pi = acos(-1); 34 const int inf = 0x3f3f3f3f; 35 const ll INF = 0x3f3f3f3f3f3f3f; 36 37 int t, l, q; 38 ll sum; 39 int a[15], mp[105][105]; 40 ll sum1[105], sum2[105]; 41 42 void init() { 43 int cnt = 0; 44 for(int i = 0; i < 4 * l; ++i) { 45 for(int j = 0; j <= i; ++j) { 46 mp[j][i-j] = a[cnt]; 47 cnt = (cnt + 1) % l; 48 } 49 } 50 sum = 0; 51 memset(sum1, 0, sizeof(sum1)); 52 memset(sum2, 0, sizeof(sum2)); 53 for(int i = 0; i < 2 * l; i++) { 54 for(int j = 0; j < 2 * l; j++) { 55 sum += mp[i][j]; 56 } 57 } 58 for(int i = 0; i < 2 * l; ++i) { 59 for(int j = 0; j < 2 * l; ++j) { 60 sum1[i] += mp[i][j]; 61 } 62 } 63 for(int j = 0; j < 2 * l; ++j) { 64 for(int i = 0; i < 2 * l; ++i) { 65 sum2[j] += mp[i][j]; 66 } 67 } 68 } 69 70 ll query(int x, int y) { 71 ll rec = 0; 72 int xx = (x + 1) / (2 * l), yy = (y + 1) / (2 * l); 73 x = (x + 1) % (2 * l), y = (y + 1) % (2 * l); 74 rec = sum * xx * yy; 75 for(int i = 0; i < y; i++) rec += xx * sum2[i]; 76 for(int i = 0; i < x; i++) rec += yy * sum1[i]; 77 for(int i = 0; i < x; i++) { 78 for(int j = 0; j < y; j++) { 79 rec += mp[i][j]; 80 } 81 } 82 return rec; 83 } 84 85 int main() { 86 //FIN; 87 scanf("%d", &t); 88 while(t--) { 89 scanf("%d", &l); 90 for(int i = 0; i < l; i++) { 91 scanf("%d", &a[i]); 92 } 93 init(); 94 scanf("%d", &q); 95 int x0, y0, x2, y2; 96 while(q--) { 97 scanf("%d%d%d%d", &x0, &y0, &x2, &y2); 98 printf("%lld\n", query(x2, y2) - query(x0 - 1, y2) - query(x2, y0-1) + query(x0-1, y0-1)); 99 } 100 } 101 return 0; 102 }
原文地址:https://www.cnblogs.com/Dillonh/p/9404289.html
时间: 2024-10-29 16:34:59