CF835C Star sky(模拟+二维前缀和)

题目大意:给你个100*100的棋盘,有些点上有点权,会随时间改变。设点权为x(x<=10),则在时间t他的点权为 (t+x)%(c+1) 。每次询问给你时间t,和一个矩阵范围(x1,y1,x2,y2),问你矩阵覆盖区域内的点权和是多少。因为棋盘范围很小,权值种类也很少,所以我们预处理一个数组cnt[k][x][y],表示(1,1,x,y)矩阵内点权为k的点的个数。用容斥原理处理就好了。。 O(c1002) 然后对于每次询问,答案即为 k=0c(k+t)%(c+1)num[k][x1][y1][x2][y2] .num数组表示(x1,y1,x2,y2)矩阵范围内点权为k的点的个数,由cnt数组利用容斥原理可以 O(1) 的得到。所以每次询问可以在 O(c) 的时间内得到。

#include <cstdio>
#include <cstring>
#define N 105
int n,q,c,cnt[11][N][N];
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int main(){
//  freopen("a.in","r",stdin);
    n=read();q=read();c=read();
    for(int i=1;i<=n;++i){
        int x=read(),y=read(),s=read();
        cnt[s][x][y]++;
    }
    for(int x=1;x<=100;++x)
        for(int y=1;y<=100;++y)
            for(int k=0;k<=c;++k)
                cnt[k][x][y]+=cnt[k][x-1][y]+cnt[k][x][y-1]-cnt[k][x-1][y-1];
    while(q--){
        int t=read(),x1=read(),y1=read(),x2=read(),y2=read(),ans=0;
        for(int k=0;k<=c;++k){
            ans+=(k+t)%(c+1)*(cnt[k][x2][y2]-cnt[k][x1-1][y2]-cnt[k][x2][y1-1]+cnt[k][x1-1][y1-1]);
        }
        printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值