AT2442 fohen phenomenon 差分

时间:2020-05-30
本文章向大家介绍AT2442 fohen phenomenon 差分,主要包括AT2442 fohen phenomenon 差分使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目链接:https://www.luogu.com.cn/problem/AT2442。洛谷的做不了的话可以用这个:https://atcoder.jp/contests/joi2017ho/tasks/joi2017ho_a

最近还有学习一些简单的差分技巧,这个博客写的不错:https://www.luogu.com.cn/blog/RPdreamer/ci-fen-and-shu-shang-ci-fen 只看了序列差分的部分。这儿还有个整理的挺好的题单:https://www.luogu.com.cn/training/4013 然后P3948就是模板题,就不写了

题意:给定n+1个点0...n,s,t。若当前点海拔A[i]>A[i+1],则气温上升(A[i]-A[i+1])*T;否则气温下降(A[i+1]-A[i])*S。q次询问,每次给出l,r,x,表示点l到点r海拔上升x,每次询问后输出最后一个点n的气温。

看到这种形式:(A[i+1]-A[i])*S,考虑差分的思想,记Bi=A[i]-A[i-1]。注意到每次给l--r之间的数加上同一个数x,变化的差值只有B[l]和B[r+1](特别注意当r=n时不考虑B[r+1]),所以先从ans里去掉上一次b[l]和b[r+1]对温度造成的影响,再进行区间加,最后再加上当前的b[l]点和b[r+1]造成的影响,即得到当前的ans。注意,当一个b的符号不同时,乘的数值是不一样的,所以要对b>0和b<0分情况写。然后要开ll,其实我不明白为什么对数组a和b开了ll才过,但我这么改了然后就过了......

这题我一开始想,区间更新,单点查询,肯定是对差分数组求前缀和。但看到每次区间加完都要查询就有点懵逼,因为用差分数组一般是先进行一波区间更新,再进行一波单点查询。仔细想想其实关键点就是区间操作后,只有两处的差分值会变化,而且询问的总是最后一个点的温度,所以每次更新答案即可

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 
 5 const int maxn=2000+10;
 6 ll a[maxn],b[maxn];
 7 int n,q,s,t,i,j,k;
 8 ll ans;
 9 
10 int main(){
11     memset(a,0,sizeof(a));
12     memset(b,0,sizeof(b));
13     ans=0;
14     //freopen("at2442.txt","r",stdin);
15     scanf("%d%d%d%d",&n,&q,&s,&t);
16     for (i=0;i<=n;i++) scanf("%lld",&a[i]);
17     for (i=1;i<=n;i++) {
18         b[i]=a[i]-a[i-1];
19         if (b[i]>0) ans-=b[i]*s;else ans+=(-b[i]*t);
20     }
21     for (i=1;i<=q;i++){
22         int l,r,x;
23         cin>>l>>r>>x;
24         if (b[l]>0) ans+=b[l]*s;else ans+=b[l]*t;
25         b[l]+=x;
26         if (b[l]>0) ans-=b[l]*s;else ans+=(-b[l]*t);
27         if (r<n){
28             if (b[r+1]>0) ans+=b[r+1]*s;else ans+=b[r+1]*t;
29             b[r+1]-=x;
30             if (b[r+1]>0) ans-=b[r+1]*s;else ans+=(-b[r+1]*t);
31         }
32         printf("%lld\n",ans);
33     }
34     return 0;
35 }
AT2442

原文地址:https://www.cnblogs.com/edmunds/p/12994144.html