题目链接: Star sky
题目大意
n颗星星, 第i颗星星坐标为
(xi,yi)
, 初始亮度为
si
, 星星最大亮度为c,
1≤xi,yi≤100,1≤c≤10,0≤si≤c
每一秒星星的亮度相对前一秒+1, 当当前亮度为c时, 下一秒亮度变为0
现在有q(
1≤q≤105
)组询问, 每次给出一个时间t, 一个矩形区域, 求在时间t时矩形区域所有星星亮度和
思路
查询次数1e5, 所以每次询问最起码要在log级别, 可以注意到坐标<=100, 最大亮度<=10, 比较小, 并且星空的情况是每c+1秒循环一次的
所以我们预处理出cnt[t][i][j] := t秒时以(0, 0), (i, j)为端点的矩形内部所有星星的亮度和
, 这样就可以
O(1)
求出任意时刻任意矩形内的亮度和
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int n, q, c, t, x1, y1, x2, y2, cnt[20][110][110];
struct P
{
int x, y, s;
}p[maxn];
int main()
{
cin >> n >> q >> c;
++c;
for(int i=0; i<n; ++i) scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].s);
for(int i=0; i<=c; ++i)
{
for(int j=0; j<n; ++j) cnt[i][p[j].x][p[j].y] += p[j].s;
for(int j=0; j<110; ++j)
for(int k=1; k<110; ++k)
cnt[i][j][k] += cnt[i][j][k-1];
for(int j=0; j<110; ++j)
for(int k=1; k<110; ++k)
cnt[i][k][j] += cnt[i][k-1][j];
for(int j=0; j<n; ++j) p[j].s = (p[j].s+1)%c;
}
for(int i=0; i<q; ++i)
{
scanf("%d%d%d%d%d", &t, &x1, &y1, &x2, &y2);
t%=c;
int ans = cnt[t][x2][y2] - cnt[t][x1-1][y2]
- cnt[t][x2][y1-1] + cnt[t][x1-1][y1-1];
printf("%d\n", ans);
}
return 0;
}