zoukankan      html  css  js  c++  java
  • CF-835C Star sky (前缀和)

    题意:天上有很多星星,每个星星有他自己的坐标和初始亮度
    每个星星的亮度在一秒内会加一如果大于最大亮度C就会变为0
    观察星星,给出视野范围(矩形)的左下角和右上角,以及观察的时间
    问视野中星星亮度总和是多少
    思路:一开始看到这道题,二维区间,想到了线段树....(不要问我为什么想到这个
    我们知道星星的亮度是在发生变化的,所以我们需要一个时间t去记录星星亮度的状态
    同时利用二维前缀和的性质求矩形区间的和。同时由于不需要更新数组所以直接预处理前缀和
    用sum[i][j][k] 表示左下角 (0,0)到右上角(i,j)统计亮度为k的星星的个数
    由容斥可以得到(或者差分性质) sum[i][j][k] = sum[i-1][j][k] +sum[i][j-1][k] -sum[i-1][j-1][k];
    (是不是有点像dp..) 在询问的时候我们就遍历所问区间中从1~c的所有亮度的总和,对其求和即为答案

    完整代码:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const  int maxn = 105;
    int n,m,c;
    int sum[maxn][maxn][15];
    void init(){
        for(int i = 1; i <= 100; i++){
            for(int j = 1; j <= 100; j++){
                for(int k = 0; k <= c; k++){
                    sum[i][j][k] += sum[i-1][j][k] + sum[i][j-1][k] - sum[i-1][j-1][k];
                }
            }
        }
    
    }
    int main(){
        while(cin>>n>>m>>c){
            memset(sum,0,sizeof(sum));
            for(int i = 0;i<n;i++){
                int x,y,z;
                cin>>x>>y>>z;
                sum[x][y][z]++;
            }
            init();
            for(int i = 0;i<m;i++){
                int t,x1,x2,y1,y2;
                int ans = 0;
                cin>>t>>x1>>y1>>x2>>y2;
                for(int k = 0;k<=c;k++){
                    //注意边界
                    int num = sum[x2][y2][k]-sum[x1-1][y2][k]-sum[x2][y1-1][k]+sum[x1-1][y1-1][k];
                    ans += ((k+t)%(c+1))*num;
                }
                cout<<ans<<endl;
            }
            
        }
    }
  • 相关阅读:
    多姿多彩的线程
    字典操作
    字符串语法
    购物车
    列表常用语法
    整数划分问题
    计算N的阶层
    判断是否是素数
    快速排序
    冒泡排序
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11347643.html
Copyright © 2011-2022 走看看