https://codeforces.com/contest/1420/problem/C2


这道题十分的锻炼思维,也让我知道了同样是差分,从前面减后面和从后面减前面是有不同的意义的。

还记得c1吗?我们是找波峰波谷的,实际上这个波峰波谷如果用差分的想法去找,可以做出c2的题。什么意思?

波峰波谷的差值一定是中间值之差的和,那么波峰波谷就是看成了能不能做差做下去。

比如1 2 5 4 3 6 7,从前往后差分是 -1,-3,1,2,-3,-1,7.会发现这样一个事情。把正数的差分全部加上去,就是最后求出的波峰波谷的最终值。

比如5 4 3找的是5 3(在上面的例子中)找出来的差值其实就是(5 - 4) + (4 - 3)

找到的那个最小值,一定波峰和波谷的值程单调性,那这两个值之间所有数的两两之差就是答案

如果画一个模拟的图5-4-3直线可以发现中间的点差不多没有影响,其实也就是这些值之间的两两之差。

那么发现了这个之后,后面的操作就是相当于把这个数组里的两个数字位置改变一下,重新进行这样类似的操作。

交换前考虑一下l的前后是不是正数,如果是就减掉,r的前后是不是正数,如果是就减掉。注意l==r-1的情况特判,防止多加多减。包含在里面一个情况就好了。

交换后看是否有相邻差为正的,正的就加上去。然后输出。swap就好了。

启发:找波峰波谷可以前往后差分去思考。

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=3e5+100;
typedef long long LL;
LL a[maxn];
void solve()
{LL n,q;cin>>n>>q;LL res=0;for(LL i=1;i<=n;i++){cin>>a[i];}for(LL i=1;i<=n;i++){if(a[i]-a[i+1]>0) res+=(a[i]-a[i+1]);}cout<<res<<endl;while(q--){LL l,r;cin>>l>>r;if(a[l-1]-a[l]>0) res-=(a[l-1]-a[l]);if(a[r-1]-a[r]>0&&l!=r-1) res-=(a[r-1]-a[r]);if(a[l]-a[l+1]>0) res-=(a[l]-a[l+1]);if(a[r]-a[r+1]>0) res-=(a[r]-a[r+1]);swap(a[l],a[r]);if(a[l-1]-a[l]>0) res+=(a[l-1]-a[l]);if(a[r-1]-a[r]>0&&l!=r-1) res+=(a[r-1]-a[r]);if(a[l]-a[l+1]>0) res+=(a[l]-a[l+1]);if(a[r]-a[r+1]>0) res+=(a[r]-a[r+1]);cout<<res<<endl;}
}
int main(void)
{cin.tie(0);std::ios::sync_with_stdio(false);LL t;cin>>t;while(t--){memset(a,0,sizeof(a)); solve();}
return 0;
}

最后补充一下线段树的dp。这个我是看别人提交的。但是我看不懂这个转移。

这个常数挺大的//写得丑了会TLE。

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
#define INF 1e18;
using namespace std;
const int maxn=3e5+100;
typedef long long LL;
int n,q;
int a[maxn];
struct Node{LL v[2][2];Node(){v[0][0]=v[1][1]=v[0][1]=v[1][0]=-INF;}Node(LL x){v[0][0]=x;v[1][1]=-x;v[0][1]=v[1][0]=-INF;}Node operator+(Node &p){Node ret;for(int i=0;i<2;i++){for(int j=0;j<2;j++){ret.v[i][j]=max({v[i][j],p.v[i][j],v[i][0]+p.v[1][j],v[i][1]+p.v[0][j]});}}return ret;}
}tree[maxn*4];
void update(int p,int l,int r,int i,int x)
{if(l==r){tree[p]=Node(x);return;}int mid=(l+r)>>1;if(i<=mid) update(p*2,l,mid,i,x);if(i>mid) update(p*2+1,mid+1,r,i,x);tree[p]=tree[p*2]+tree[p*2+1];
}
int main(void)
{//cin.tie(0);std::ios::sync_with_stdio(false);int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&q);//   for(LL i=0;i<=n+10;i++) a[i]=0,update(1,1,n,i,a[i]); for(int i=1;i<=n;i++) cin>>a[i],update(1,1,n,i,a[i]);printf("%lld\n",tree[1].v[0][0]);while(q--){int l,r;scanf("%d%d",&l,&r);swap(a[l],a[r]);update(1,1,n,l,a[l]);update(1,1,n,r,a[r]);printf("%lld\n",tree[1].v[0][0]);}}
return 0;
}

C2 - Pokémon Army (hard version)(思维+差分/线段树+dp)详解相关推荐

  1. C2. Pokémon Army (hard version)

    C2. Pokémon Army (hard version) http://codeforces.com/problemset/problem/1420/C2 题解:序列是一个起伏的形状,答案其实就 ...

  2. C2. Pokémon Army (hard version)(贪心分治)

    C2. Pokémon Army (hard version) (贪心&分治) 思路:局部最优解→\rightarrow→全局最优解. 显然答案数组长度为奇数,因为ai>0a_i> ...

  3. 差分 ---- Codeforces Round #672 (Div. 2):C2. Pokémon Army (hard version)[差分的思想]

    题目链接 题目大意:就算给你一序列,按照顺序出若干个数组成一个的序列,然后对这个序列定义一个权值就算奇数位置的和减去偶数位置的和,问你能的到的最大的权值是多少? **a1 - a2 + a3 - a4 ...

  4. Codeforces Round #672 (Div. 2) C2 - Pokémon Army (hard version)(贪心,维护变化值)

    x数组里选一个子数组y(原数组顺序),y1-y2+y3-y4+- 的最大值 然后还有q次交换操作,每次修改之后都要输出新的最大值 (1)如果没有修改,单纯对于当前数组考虑,我们最后选出来的点肯定是波峰 ...

  5. codeforces C2. Pokémon Army (hard version)(模拟)

    原题链接 //#pragma GCC optimize("Ofast") //#pragma GCC target("avx,avx2,fma") //#pra ...

  6. 1420C1. Pokémon Army (easy version)

    C1. Pokémon Army (easy version):题目 题意:选择其中一部分,按照+-依此计算,求总和 思路:找到局部最大值,然后减去局部最小值,依此找. #include <bi ...

  7. C1. Pokémon Army (easy version)(DP)

    C1. Pokémon Army (easy version)(DP) 思路:dpdpdp. 考虑:分数组长度的奇偶性进行dpdpdp. 令dp[i][0]dp[i][0]dp[i][0]表示前iii ...

  8. Educational Codeforces Round 67 (Rated for Div. 2)(D思维题 线段树/E树形dp(换根dp) 二次扫描与换根法)

    心得 D写了个假算法被hack了wtcl- E据涛神说是二次扫描与换根法,看了看好像和树形dp差不多 F概率dp G费用流 回头再补 思路来源 马老师 归神 贤神等代码 http://www.mami ...

  9. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

最新文章

  1. ERP与EWM集成配置---ERP 端(一)
  2. java例程练习(批量修改文件后缀名)
  3. 西电计算机学院(原软件学院)软件工程考研复试
  4. php is_post,PHP发送get、post请求的6种方法简明总结
  5. 对称密码的编程使用(DES、3DES、AES)
  6. C++ vector 遍历修改汇总
  7. 块内拉升lisp_求大神告知,如何用LISP实现块数量分类统计程序,最好统计后列出表格。谢谢了。...
  8. 设计模式笔记零:设计模式简介
  9. 雅思考试流程、需要具体注意些什么、怎么复习?
  10. 三种存储类型和三种存储方式
  11. Python爬虫入门教程【11】:半次元COS图爬取
  12. 华为设备BFD实战,双向转发检测BFD详解,理论+实战+抓包分析
  13. iOS 应用程序的生命周期
  14. 前缀和-python
  15. 最新emoji表情代码大全_周六最美早晨好问候语图片大全 早晨好图片祝福 最新早上好问候动态表情图片...
  16. android实现多画面播放,快手同框怎么弄?怎样制作多个视频同框?安卓手机上制作三个不同的视频同框播放...
  17. 无线密码破解工具 - Aircrack-ng
  18. kafka的基本概念和工作流程分析
  19. 第一次看母亲细嚼慢咽地吃饭,欣慰还是心酸?
  20. 经颅聚焦超声信号仿真(MATLAB k-Wave仿真)

热门文章

  1. 期货投资盈亏比怎么算(期货盈亏怎么算的)
  2. 加湿器-香薰机的设计方案(单片机程序+PCB)超声波震荡方式 原理图+PCB+源代码+详细设计说明
  3. 模电数电单片机综合开发系统实验装置QY-MS535K
  4. 2021年三季度中国医疗服务行业A股上市企业营收排行榜:国际医学于1月17日起戴帽,简称变更为“ST国医”(附热榜TOP37详单)
  5. NOI 4.6 贪心 2407:书架
  6. 鞋长度和欧美的标准宽度换算表
  7. 2023北京叶黄素展/北京视力矫正设备展/北京眼睛医学康复展
  8. #fff 与 #ffffff 一样是白色
  9. Android 编译速度优化黑科技 - RocketX
  10. uni--打包ios越狱包失败