1. 程式人生 > >Codeforces 835C - Star sky - [二維前綴和]

Codeforces 835C - Star sky - [二維前綴和]

http 時間 namespace 範圍 只需要 ces pro 長方形 二維前綴和

題目鏈接:http://codeforces.com/problemset/problem/835/C

題意:

在天空上劃定一個直角坐標系,有 $n$ 顆星星,每顆星星都有坐標 $(x_i,y_i)$,星星初始亮度為 $s_i$,所有星星的亮度有個上限 $c$。

在時刻 $0$,每顆星星都是初始亮度 $s_i$,然後每過一個單位時間,星星亮度都增加 $1$,如果亮度一旦超過 $c$ 就立刻變為 $0$。

現在有 $q$ 次觀察天空的機會,觀察時刻為 $t_i$,觀察的視野為左下角為 $(x_{1i},y_{1i})$,右上角為 $(x_{2i},y_{2i})$ 的平行於坐標軸的長方形。要求出每次觀察時,在視野中的星星的亮度和。

題解:

首先星星亮度是周期變化的,周期長度是 $c+1$,所以我們只需要求出周期內每個時刻星星的亮度。

然後我們再用一個二維前綴和,就能 $O(1)$ 查出每個時刻任意長方形範圍的星星亮度和。

註意一點,可能多個星星重疊在一個坐標上。

AC代碼:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const int C=13;
const int X=105, Y=105;
int n,q,c;
struct Star{
    int x,y,s;
}star[N];
int sum[C][X][Y]; int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); cin>>n>>q>>c; for(int i=1;i<=n;i++) cin>>star[i].x>>star[i].y>>star[i].s; memset(sum,0,sizeof(sum)); for(int t=0;t<=c;t++) { for(int
i=1;i<=n;i++) sum[t][star[i].x][star[i].y]+=(star[i].s+t)%(c+1); for(int x=1;x<=100;x++) for(int y=1;y<=100;y++) sum[t][x][y]+=sum[t][x-1][y]+sum[t][x][y-1]-sum[t][x-1][y-1]; } for(int i=1,t,x1,y1,x2,y2;i<=q;i++) { cin>>t>>x1>>y1>>x2>>y2; cout<<sum[t%(c+1)][x2][y2]-sum[t%(c+1)][x2][y1-1]-sum[t%(c+1)][x1-1][y2]+sum[t%(c+1)][x1-1][y1-1]<<"\n"; } }

Codeforces 835C - Star sky - [二維前綴和]