zoukankan      html  css  js  c++  java
  • AT2442 フェーン現象 (Foehn Phenomena)

    题目地址

    原题地址

    题解

    其实就是一个区间加,单点查询的问题
    当然可以线段树/树状数组做,但是这两个做法要分类讨论所以代码会比较多
    我们考虑一种更简便的做法
    差分!
    因为温度只和海拔差有关,这相当于题目赤裸裸的告诉我们要差分
    那么我们考虑每次修改海拔对答案的影响
    对于中间那一段,显然对答案的贡献是不会变的
    会变的只有(l,r+1)这两个地方,分类讨论高低太麻烦了,我们可以先在答案中减去原来的数对答案的影响,再给答案加上修改后的数对答案的影响
    代码语言即为

    sum -= p(d[l]); d[l] += x; sum += p(d[l]);
    //p为算影响的函数,d为差分数组,sum为答案
    

    于是我们得到了一个预处理(O(n)),单次询问(O(1))的算法
    需要注意的一个点是,要特判(r=n)的情况,在这种情况下,我们只需要更改左端点即可
    以及将差分数组和前缀和开longlong

    #include <bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define N 200010
    int n, m, s, t;
    ll a[N], d[N];
    ll sum = 0;
    
    ll p(ll x) { return x * (x > 0 ? s : t); }
    
    int main() {
    	scanf("%d%d%d%d", &n, &m, &s, &t);
    	ll L; scanf("%lld", &L);
    	for(int i = 1; i <= n; i ++) {
    		scanf("%lld", &a[i]);
    		d[i] = a[i] - L; L = a[i];
    		sum += p(d[i]);
    	}
    	for(int i = 1; i <= m; i ++) {
    		int l, r; ll x;
    		scanf("%d%d%lld", &l, &r, &x);
    		sum -= p(d[l]); d[l] += x; sum += p(d[l]);
    		if(r == n) {printf("%lld
    ", -sum); continue;}
    		sum -= p(d[r + 1]); d[r + 1] -= x; sum += p(d[r + 1]);
    		printf("%lld
    ", -sum);
    	}
    	return 0;
    }
    
  • 相关阅读:
    一文读懂Lua元表
    React-Antd Pro环境搭建
    如何在QT项目中引入Boost库
    .NET Core RSA PKCS8 格式 签名/验签
    Chrome控制台Network请求过滤
    字符串拼接null值问题
    复制文件夹需要考虑的问题
    [闻缺陷则喜]关于boost的想法
    公共库开发组
    docker-compose 一键部署分布式配置中心Apollo
  • 原文地址:https://www.cnblogs.com/henry-1202/p/10146836.html
Copyright © 2011-2022 走看看