二维前缀和

一维前缀和 :

  这个优化 , 可以在 O (1) 的时间内计算出一个序列的和 ,

二维前缀和 :

  对于一个矩阵 , 也可以在 O (1) 的时间内计算出矩阵 (x1~x2)( y1 ~ y2 ) 的和 。

  sum[ i ] [ j ] 表示矩阵 1 ~ i , 1 ~ j 的和 , 那么由容斥原理知 sum[ 0 ] [ j ] 和 sum [ i ] [ 0 ] 均为 0 。

  则  s[ x1 ~ x2 ] [ y1 ~ y2 ] = sum[ x2 , y2 ] + sum [ x1 - 1 ] [ y1 - 1 ] - sum [ x1 - 1 ][ y2 ] - sum [ x2 ] [ y1-1 ] 。

The Cartesian coordinate system is set in the sky. There you can see n stars, the i-th has coordinates (xi, yi), a maximum brightness c, equal for all stars, and an initial brightness si (0?≤?si?≤?c).

Over time the stars twinkle. At moment 0 the i-th star has brightness si. Let at moment t some star has brightness x. Then at moment (t?+?1) this star will have brightness x?+?1, if x?+?1?≤?c, and 0, otherwise.

You want to look at the sky q times. In the i-th time you will look at the moment ti and you will see a rectangle with sides parallel to the coordinate axes, the lower left corner has coordinates (x1i, y1i) and the upper right — (x2i, y2i). For each view, you want to know the total brightness of the stars lying in the viewed rectangle.

A star lies in a rectangle if it lies on its border or lies strictly inside it.

Input

The first line contains three integers n, q, c (1?≤?n,?q?≤?105, 1?≤?c?≤?10) — the number of the stars, the number of the views and the maximum brightness of the stars.

The next n lines contain the stars description. The i-th from these lines contains three integers xi, yi, si (1?≤?xi,?yi?≤?100, 0?≤?si?≤?c?≤?10) — the coordinates of i-th star and its initial brightness.

The next q lines contain the views description. The i-th from these lines contains five integers ti, x1i, y1i, x2i, y2i (0?≤?ti?≤?109, 1?≤?x1i?<?x2i?≤?100, 1?≤?y1i?<?y2i?≤?100) — the moment of the i-th view and the coordinates of the viewed rectangle.

Output

For each view print the total brightness of the viewed stars.

Example

Input

2 3 31 1 13 2 02 1 1 2 20 2 1 4 55 1 1 5 5

Output

303

Input

3 4 51 1 22 3 03 3 10 1 1 100 1001 2 2 4 42 2 1 4 71 50 50 51 51

Output

3350

Note

Let‘s consider the first example.

At the first view, you can see only the first star. At moment 2 its brightness is 3, so the answer is 3.

At the second view, you can see only the second star. At moment 0 its brightness is 0, so the answer is 0.

At the third view, you can see both stars. At moment 5 brightness of the first is 2, and brightness of the second is 1, so the answer is 3.

如果这题是遍历 所有的点 , 那么一定会超时 , 由于灯亮度变化范围较小 , 可以借助二维前缀和 , 将一定范围内不同亮度的灯全部合并到一起 , 最后对于 每次询问 ,只需要遍历所有的亮度即可 。

代码示例 :

/*
 * Author:  renyi
 * Created Time:  2017/8/29 9:23:49
 * File Name:
 */
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <time.h>
using namespace std;
const int maxint = -1u>>1;
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define ll long long
int dp[105][105][15] ;

int main() {
    int n , q , c ;
    int x , y , c1 ;

    while ( ~scanf ( "%d%d%d" , &n , &q , &c) ) {
        memset ( dp , 0 , sizeof(dp) ) ;
        for ( int i = 0 ; i < n ; i++ ) {
            scanf ( "%d%d%d" , &x , &y , &c1 ) ;
            dp[x][y][c1]++ ;
        }

        for ( int i = 1 ; i <= 100 ; i++ ) {
            for ( int j = 1 ; j <= 100 ; j++ ) {
                for ( int k = 0 ; k <= 10 ; k++ ) {
                    dp[i][j][k] += dp[i-1][j][k]+dp[i][j-1][k]-dp[i-1][j-1][k] ;
                }
            }
        }

        int t , x1 , y1 , x2 , y2 ;
        while ( q-- ) {
            scanf ( "%d%d%d%d%d" , &t , &x1 , &y1 , &x2 , &y2 ) ;

            int sum = 0 ;
            for ( int i = 0 ; i <= c ; i++ ) {
                int s = dp[x2][y2][i] + dp[x1-1][y1-1][i] - dp[x1-1][y2][i] - dp[x2][y1-1][i] ;
                int l = ( t + i ) % ( c + 1 ) ;
                sum += s * l ;
            }
            printf ( "%d\n" , sum ) ;
        }
    }

    return 0;
}
时间: 2024-08-10 19:01:56

二维前缀和的相关文章

openjudge1768 最大子矩阵[二维前缀和or递推|DP]

总时间限制:  1000ms 内存限制:  65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵. 比如,如下4 * 4的矩阵 0 -2 -7 09 2 -6 2-4 1 -4 1-1 8 0 -2 的最大子矩阵是 9 2-4 1-1 8 这个子矩阵的大小是15. 输入 输入是一个N * N的矩阵.输入的第一行给出N (0 < N <= 100).再后面的若干行中,依次(首先从左到右给出第一行的N个整数,再从左到右给

Good Bye 2015 C. New Year and Domino 二维前缀

C. New Year and Domino They say "years are like dominoes, tumbling one after the other". But would a year fit into a grid? I don't think so. Limak is a little polar bear who loves to play. He has recently got a rectangular grid with h rows and w

计蒜客模拟赛D1T1 蒜头君打地鼠:矩阵旋转+二维前缀和

题目链接:https://nanti.jisuanke.com/t/16445 题意: 给你一个n*n大小的01矩阵,和一个k*k大小的锤子,锤子只能斜着砸,问只砸一次最多能砸到多少个1. 题解: 将原矩阵顺时针旋转45°,二维前缀和预处理,然后枚举每一个可能砸到的正方形之和并取最大. 注:枚举的正方形的四个顶点必须是从原矩阵璇转过来的点,代码中用vis数组判断. #include <iostream> #include <stdio.h> #include <string.

弱校联盟10.7 I. Special Squares(二维前缀和)

题目链接: I. Special Squares There are some points and lines parellel to x-axis or y-axis on the plane. If arbitrary chosen two lines parallel to x-axis and two lines parallel to y-axis, one rectangle, or sometimes a square, will be formed. If a square i

CDOJ 1256 二维前缀和处理

昊昊喜欢运动 他NN 天内会参加MM 种运动(每种运动用一个[1,m][1,m] 的整数表示) 舍友有QQ 个问题 问昊昊第ll 天到第rr 天参加了多少种不同的运动 Input 输入两个数NN , MM (1≤N≤20001≤N≤2000 , 1≤M≤1001≤M≤100 ); 输入NN 个数aiai 表示在第i天昊昊做了第aiai 类型的运动; 输入一个数QQ (1≤Q≤1061≤Q≤106 ); 输入QQ 行 每行两个数 ll , rr (1≤l≤r≤n1≤l≤r≤n ); Output

二维前缀和 - 算法学习 - 输入输出优化

2017-08-27 11:11:38 writer:pprp 二维前缀和主要用到了容斥定理,具体实现还是有点复杂的 详见代码: /* @theme:二维前缀和 @writer:pprp @declare:用到容斥定理 @date:2017/8/27 */ #include <bits/stdc++.h> using namespace std; const int maxn = 1010; int n, m, a[maxn][maxn]; //输入优化 inline int read() {

杭电2018多校第四场(2018 Multi-University Training Contest 4) 1005.Problem E. Matrix from Arrays (HDU6336) -子矩阵求和-规律+二维前缀和

6336.Problem E. Matrix from Arrays 不想解释了,直接官方题解: 队友写了博客,我是水的他的代码 ------>HDU 6336 子矩阵求和 至于为什么是4倍的,因为这个矩阵是左上半边有数,所以开4倍才能保证求的矩阵区域里面有数,就是图上的红色阴影部分,蓝色为待求解矩阵. 其他的就是容斥原理用一下,其他的就没什么了. 代码: 1 //1005-6336-矩阵求和-二维前缀和+容斥-预处理O(1)查询输出 2 #include<iostream> 3 #in

前缀和,二维前缀和!

前缀和 定义 用空间换取效率,做一个预处理,然后可以\(O(1)\)的查询某个区间的值的和. 实现 设\(s_i\)为第\(i\)个数\(a_i\)的前缀和,则\(s_i=s_i-1+a_i\) 当要查找区间的和时只要把对应的起点终点的元素相减即可. 例题 Educational Codeforces Round 30B Balanced Substring 翻译 给你一个长度至多为\(100000\)的\(01\)串,其中含有相同\(0\),\(1\)个数的子串被称为"平衡串",问你

切蛋糕(二分)(二维前缀和)

观察数据范围,n*m比较小,所以我们预先处理出前缀和. 然后我们可以考虑写一个函数来计算二维前缀和(二维前缀和大家都会的吧qwq,那我就不说了,就是要注意一下哪个是横轴哪个是纵轴) 之后就是二维上的二分位置,然后check看看符不符合二分出来的ans. 注:一半求最大化最小值和最小化最大值的问题,都可以往二分想.我们可以把最优化问题二分后来check转化为判定问题. #include<cstdio> #include<cstring> #include<iostream>