2020牛客寒假算法基础集训营6.F——十字列阵【计算】

题目传送门


题目描述

小 Q 新学会了一种魔法,可以对一个 N行M列 的网格上的敌人造成伤害
第 i 次使用魔法可以对网格上的一个十字形区域(即第 xi 行和第 yi 列的并)中的每个格子上的敌人造成 zi 点伤害
现在小 Q 一共使用了 H 次魔法,你需要在所有的施法完成之后统计造成伤害的情况,详见输出描述
提醒:本题输入规模较大,请使用高效的输入方式
1 ≤ H ≤ 500 , 000 ;    1 ≤ x i , y i , z i , N , M ≤ 2000 ;    1 ≤ x i ≤ N ;    1 ≤ y i ≤ M 1≤H≤500,000;\ \ 1≤xi,yi,zi,N,M≤2000 ;\ \ 1≤xi≤N;\ \ 1≤yi≤M 1H500,000;  1xi,yi,zi,N,M2000;  1xiN;  1yiM


输入描述:

第一行 3 个数字 N,M,H
接下来 H 行,每行 3 个正整数 xi,yi,zi

输出描述:

为了避免大量的输出,假设第 i 行第 j 列受到的总伤害是 w i j w_{ij} wij
你只需要输出 Σ w i j ( i + j ) Σw_{ij}(i+j) Σwij(i+j) 1 0 9 + 7 10^9+7 109+7 取模的结果即可


输入

5 5 5
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5


输出

890


说明

造成伤害的情况是:
1 3 4 5 6
3 2 5 6 7
4 5 3 7 8
5 6 7 4 9
6 7 8 9 5
补充的说明:
890 = 1*(1+1)+3*(1+2)+4*(1+3)+…+5*(5+5),一共25项累加得到890


题解

  • 数据范围很大,我们需要加速过程
  • 考虑如图在这里插入图片描述
  • 假设在 ( x = 3 , y = 2 ) (x=3,y=2) (x=3,y=2) 位置 添加 Δ \Delta Δ
  • 那么我们来思考它的贡献,只有 x = 3 x=3 x=3 的行, y = 2 y=2 y=2 的列有 Δ \Delta Δ 的贡献。值就是图中写的
  • 那么我们可以总结一下规律,就可以在 O ( H ) O(H) O(H) 复杂度内解决问题

AC-Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int maxn = 2e3+7;

int main(){
    ll N, M, H;    while(scanf("%lld%lld%lld", &N, &M, &H) == 3) {
        ll n = (1+N)*N/2; // 1+...+N
        ll m = (1+M)*M/2;
        ll ans = 0;
        for(int i = 0; i < H; ++i) {
            ll x, y, z;    scanf("%lld%lld%lld", &x, &y, &z);
            ans = (ans + z * (n + m + (N-1)*y % mod + (M-1)*x % mod) % mod) % mod;
        }
        printf("%lld\n", ans);
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值