题目大意:

给你一个 100*100 的地图,然后告诉你这个图中有若干个点有星星,每个星星有一个初始亮度 s ,每个星星的亮度随着时间的变化而周期性变化。现在要进行 1e5 次查询,每次查询给你一个矩阵,和一个时间 t ,让你求 t 时刻该矩阵内每个星星乘他们的亮度的和。

注:这里有一个坑点就是,每个点会有多个星星,因为这个卡了好久。其实看数据范围也能看出来, 100*100 的格子里要放 1e5 的星星,肯定有重叠的。

分析:

确定状态:

dp [ i ] [ j ] [ k ] 表示点(i,j)和点(0,0)确定的矩阵里面,0时刻亮度为 k 的星星个数。(包括边界)

状态转移方程:

dp [ i ] [ j ] [ k ] = dp [ i ] [ j-1 ] [ k ] + dp [ i-1 ] [ j ] [ k ] - dp [ i-1 ] [ j-1 ] [ k ] + num [ i ] [ j ] [ k ] ;

边界条件:

dp [ 0 ] [ j ] [ k ] = 0 ;(0<=j<1e5,0<=k<=10)
dp [ i ] [ 0 ] [ k ] = 0 ;(0<=i<1e5,0<=k<=10)

代码:

#include<bits/stdc++.h>
using namespace std;
int n,q,c;
int num[105][105][13]={0};
int mapx[105][105];

int main()
{
    scanf("%d%d%d",&n,&q,&c);
   /* for(int i=0;i<105;i++) { for(int j=0;j<105;j++) { mapx[i][j]=-1; } }*/
    int temp_x,temp_y,temp_s;
    for(int i=0;i<n;i++)
    {
        scanf("%d%d%d",&temp_x,&temp_y,&temp_s);
        //temp_s%=(c+1);
        num[temp_x+1][temp_y+1][temp_s]++;
    }
    for(int i=1;i<105;i++)
    {
        for(int j=1;j<105;j++)
        {
            for(int k=0;k<=c;k++)
            {
                num[i][j][k]+=(num[i-1][j][k]+num[i][j-1][k]-num[i-1][j-1][k]);
            }
            //if(mapx[i][j]!=-1)num[i][j][mapx[i][j]]++;
        }
    }
    int t,x1,y1,x2,y2;
    for(int i=0;i<q;i++)
    {
        //int temp_t;
        scanf("%d%d%d%d%d",&t,&x1,&y1,&x2,&y2);
        x1++;y1++;x2++;y2++;
        //t+=temp_t;
        t%=(c+1);
        int tal=0;
        for(int k=0;k<=c;k++)
        {
            //int w=(k+c-t)%(c+1);
            int ans = num[x2][y2][k] - num[x2][y1-1][k] - num[x1-1][y2][k] + num[x1-1][y1-1][k];
            if(ans>0) tal = tal + ans * ((k+t)%(c+1));
        }
        printf("%d\n",tal);
    }
}