Problem E. Matrix from Arrays(杭电2018年多校第四场+思维+打表找循环节)

题目链接: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 }

 

posted @ 2018-08-01 22:17  Dillonh  阅读(368)  评论(0编辑  收藏  举报