cf 1406D. Three Sequences (数学 差分)

 题目链接:传送门


 题目思路:

  ai = bi + ci  , 其中b是非降序列,c是非升序列

  ci-1 ≥ c ↔  ai-1 - bi-1 ≥ ai - b

  bi - bi-1 ≥ ai - ai-1  , bi-1 - bi-2 ≥ ai-1 - ai-2 , ... 不等式叠加可得:

  bn - b1 >= sum , 定义 sum = ∑ni=di , di = ai - ai-1

  bn ≥ sum + b1

  又 c1 = a1 - b1

  现在要使 ans = max(bn , c1) 最小化且bn 和 c1都是以 b1 为自变量的一次函数, 可得 sum + b1 = a1 - b1 -> b1 = (a1 - sum) /2  (b1 取整数) 

  由于构造了 查分数组d , 区间修改可以转变为单点修改,然后动态修改sum的值即可;


 

 

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 typedef pair<int,int> pii;
 5 typedef pair<LL,LL> pLL;
 6 #define pb push_back
 7 #define mk make_pair
 8 #define fi first
 9 #define se second
10 #define ls (i<<1)
11 #define rs (i<<1|1)
12 #define mem(a,b) memset(a,b,sizeof(a))
13 const int N=1e6+5;
14 const int inf=0x3f3f3f3f;
15 LL read()
16 {
17     LL x=0,f=1;
18     char ch=getchar();
19     while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); }
20     while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
21     return f*x;
22 }
23 LL a[N],d[N],sum,n;
24 void update(int pos,LL x)
25 {
26     if(pos>1&&pos<=n) sum+=max(0LL,d[pos]+x)-max(0LL,d[pos]);
27     d[pos]+=x;
28 }
29 int main()
30 {
31     n=read();
32     for(int i=1;i<=n;i++) a[i]=read();
33     for(int i=1;i<=n;i++) d[i]=a[i]-a[i-1];
34     for(int i=2;i<=n;i++) sum+=max(d[i],0LL);
35     LL x=(d[1]-sum)/2;
36     printf("%lld\n",max(d[1]-x,x+sum));
37     int m=read();
38     for(int i=1;i<=m;i++)
39     {
40         LL l=read(),r=read(),y=read();
41         update(l,y);
42         update(r+1,-y);
43         x=(d[1]-sum)/2;
44         printf("%lld\n",max(d[1]-x,x+sum));
45     }
46     return 0;
47 }
View Code
复制代码

 

posted @   DeepJay  阅读(220)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示