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;
            }
            
        }
    }
  • 相关阅读:
    C 习题
    gcc
    几何视角看线性方程组解的情况
    JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式)
    为什么重写了equals(),还要重写hashCode()?
    关于ArrayList的越界问题?
    通过实例聊聊Java中的多态
    java异常处理实例分析
    Java: Integer用==比较时127相等128不相等的原因
    Java并发编程:Lock
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11347643.html
Copyright © 2011-2022 走看看