2022.03.23绝世武功

题目描述

小明在练习绝世武功, n 个练功桩排成一排,一开始每个桩的损伤为 0。

接下来小明会练习 m 种绝世武功,每种武功都会对 [l, r]区间分别造成 [s,e] 的伤害。

这个伤害是一个等差序列。例如 l=1,r=4,s=2,e=8 ,则会对 1−4 号练功桩造成2, 4, 6, 8点损伤。

小明想让你统计一下所有练功桩的损伤的和。

输入描述

第一行输入 n,m,代表练功桩的数量和绝世武功的种类数。

接下来 mm 行输入 44 个整数 l, r, s, e。

1≤n≤107,1≤m≤3×105,1≤l,r≤n1 \leq n \leq 10^7 , 1\leq m \leq 3 \times 10 ^ 5 , 1\leq l, r \leq n1n107,1m3×105,1l,rn

输出描述

输出一个整数代表所有练功桩的损伤和, 题目保证所有输入输出都在 [0,9×1018][0, 9 \times 10^{18}][0,9×1018]

输入

6 2
1 5 2 10
2 4 1 1

输出

33

思路

明明可以直接求和公式的题,一开始竟然想到用差分,以此题警戒自己。
此外,在蓝桥杯比赛中,不用快读可能超时!

代码

    void test() throws IOException {
        Reader cin = new Reader();
        int n = cin.nextInt();
        int m = cin.nextInt();
        long res = 0;
        for(int i = 0; i < m; i++) {
          long l = cin.nextLong(), r = cin.nextLong(), s = cin.nextLong(), e = cin.nextLong();
          res += ((s+e)*(r-l+1))/2;
        }

        System.out.println(res);
    }

差分代码

    public static void main(String[] args) {
        
      Scanner cin = new Scanner(System.in);
      int n = cin.nextInt();
      int m = cin.nextInt();
      int[] a = new int[10000006];
      for(int i = 0; i < m; i++) {
        int l = cin.nextInt();
        int r = cin.nextInt();
        int s = cin.nextInt();
        int e = cin.nextInt();
        int d = (e-s) / (r-l);
        int sm = s;
        a[l] += s;
        for(int k = l+1; k <= r; k++) {
          sm += d;
          a[k] += d;
        }
        a[r+1] -= sm;
      }
      long res = 0;
      for(int i = 1; i <= n; i++) {
        a[i] += a[i-1];
        res += a[i];
      }
      
      System.out.println(res);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值