Codeforces Round #427 (Div. 2) C. Star sky 二维前缀和

来源:互联网 发布:mac设置airdrop 编辑:程序博客网 时间:2024/06/01 20:46

题目链接: Star sky

题目大意

n颗星星, 第i颗星星坐标为(xi,yi), 初始亮度为si, 星星最大亮度为c, 1xi,yi100,1c10,0sic
每一秒星星的亮度相对前一秒+1, 当当前亮度为c时, 下一秒亮度变为0
现在有q(1q105)组询问, 每次给出一个时间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;}
阅读全文
0 0
原创粉丝点击