分析:
都说是裸差分 那就线段树做(
海拔的上升与下降 就区间修改 答案就单点查询
具体的就跟题意模拟了
然后注意
a
0
a_0
a0是
0
0
0 那
n
,
x
,
y
n,x,y
n,x,y啥的都要加
1
1
1 但必须在快读
+
1
+1
+1 不然就会
W
A
WA
WA
害我调了好久(
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<bitset>
#define Ctnue continue
//#pragma GCC optimize(2)
#define reg register
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int N=2e5+5;
int n,m,s,t;
ll ans,a[N],sum[N<<2],w1,w2,fad;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
return x*f;
}
void down(int now){
sum[now<<1]+=sum[now];
sum[now<<1|1]+=sum[now];
sum[now]=0;
}
void Add(int now,int l,int r,int L,int R,int value)
{
if(L<=l&&r<=R)
{
sum[now]+=value;
return;
}
int mid=(l+r)>>1;
down(now);
if(L<=mid) Add(now<<1,l,mid,L,R,value);
if(mid<R) Add(now<<1|1,mid+1,r,L,R,value);
}
ll query(int now,int l,int r,int L,int R)
{
if(l==r) return sum[now]+a[l];
int mid=(l+r)>>1;
down(now);
if(L<=mid) return query(now<<1,l,mid,L,R);
else return query(now<<1|1,mid+1,r,L,R);
}
void add(ll a,ll b)
{
if(b>a) ans+=(b-a)*t;
else ans-=(a-b)*s;
}
void sub(ll a,ll b)
{
if(b>a) ans-=(b-a)*t;
else ans+=(a-b)*s;
}
int main()
{
n=read()+1;m=read();
t=read();s=read();
a[1]=read();
for(int i=2;i<=n;i++)
{
a[i]=read();
if(a[i-1]<a[i]) ans-=(a[i]-a[i-1])*t;
else ans+=(a[i-1]-a[i])*s;
}
while(m--)
{
int x,y,val;
x=read()+1;y=read()+1;
val=read();
w2=query(1,1,n,x,y);x--;
w1=query(1,1,n,x,y);x++;
add(w1,w2);
if(y!=n)
{
fad=x;x=y;
w1=query(1,1,n,x,y);x++;
w2=query(1,1,n,x,y);x=fad;
add(w1,w2);
}
Add(1,1,n,x,y,val);
w2=query(1,1,n,x,y);x--;
w1=query(1,1,n,x,y);x++;
sub(w1,w2);
if(y!=n)
{
fad=x;x=y;
w1=query(1,1,n,x,y);x++;
w2=query(1,1,n,x,y);
sub(w1,w2);
}
printf("%lld\n",ans);
}
return 0;
}