C. Star sky(Codeforces Round #427 (Div. 2) C)

題目大意:給在100*100的網格上,有n顆星星, 每顆星星有自己的亮度,最大亮度是c,每過t秒,星星的亮度就會加t,如果亮度超過了c,就會變成0,然後繼續從0開始增加。現在有q次查詢, 每次查詢會輸入一個時間t,和兩個點,要求輸出,在t時間下,這兩個點所組成的矩形中星星亮度的和。
題目思路:首先我們現將輸入的查詢全部存起來,輸入的時候將每個查詢的t對(c+1) 取模, 然後對t進行排序。然後我們對查詢中的t從小到大進行處理,t的值一共最多也就c+1種(c<= 10)。對於每個t, 我們先打出這樣一個網格map[100][100], map[i][j]的意思是在座標i, j 這個點上星星的亮度值,每顆星星的亮度加上t後要對(c+1)取模,同一個點上可能有兩顆星星,亮度直接相加就可以了。然後求出對於每個i來說, j的前綴和。也就是說現在map[i][j] 表示的是當x == i時, 對於y軸前j位置的亮度和是多少(這個可以理解爲一個線段的貢獻值)。 然後對於每個查詢來說我們只需要,將map[x1][y2] + map[x1+1][y2] + ……+map[x2][y2] - (map[x1][y1-1] + map[x1+1][y1-1] + ……+map[x2][y1-1] )這個就是查詢的答案了,這樣一共處理c次
複雜度在o(cn) + o(q*100) + o(10000) 完全可以接受。
代碼如下:

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
#define Max_N 100000+100
int x[Max_N], y[Max_N], s[Max_N];
int map1[110][110];
int n, q, c;
struct point{
    int x1, y1;
    int x2, y2;
    int t;
    int num;
};
point que[Max_N];
bool cmp(const point &a, const point &b)
{
    return a.t < b.t;
}
int b[110][110];
int ans[Max_N];
int main()
{ 
    cin >> n >> q >> c;
    for (int i = 1; i <= n; i++) {
        scanf("%d%d%d", &x[i], &y[i], &s[i]);
    }
    for (int i = 0; i < q; i ++) {
        scanf("%d%d%d%d%d", &que[i].t, &que[i].x1, &que[i].y1, &que[i].x2, &que[i].y2);
        que[i].t %= (c+1);
        que[i].num = i;
    }
    sort (que, que + q, cmp);
    //cout << que[0].t << endl;
    int l = 0;
    memset(ans, 0, sizeof(ans));
    for (int i = 0; i <= c; i++) {
        memset(map1, 0, sizeof(map1));
        memset(b, 0, sizeof(b));
        for (int j = 1; j <= n; j++) {
            map1[x[j]][y[j]] += (s[j] + i) % (c+1);
        }
        for (int j = 1; j <= 100; j++) {
            for (int w = 1; w <= 100; w++) {
                map1[j][w] += map1[j][w-1];
            }
        }
        for (; l < q; l++) {
            if (que[l].t != i) break;
            int _x1 = que[l].x1;
            int _y1 = que[l].y1;
            int _x2 = que[l].x2;
            int _y2 = que[l].y2;
            int w = que[l].num;
            int ans1 = 0;
            int ans2 = 0;
            for (int ss = _x1; ss <= _x2; ss++) {
                ans1 += map1[ss][_y1-1];
                ans2 += map1[ss][_y2];
            }
            ans[w] = ans2 - ans1;
        }
    }
    for (int i = 0; i < q; i++)
        cout << ans[i] << endl;

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章