题意:给你一个序列,让你任意选出一个子序列,使得奇数位和减去偶数位和最大。同时有q个询问,输出每次交换完a[l]和a[r]后的上述最大值。

思路:首先肯定可以确定选出来的子序列长度为奇数,因为偶数位只会让我们的值减少。

我们先从简单的情况开始入手,当一个序列极大值只有一个时(只有一个波峰):



那我肯定只选那个波峰(极大值)就好了,只选一个。

当这个序列有多个波峰时:



首先我还是会选一个波峰,a[\(x{_1}\)]。但是发现光只选这个好像很亏。我们肯定想尽量拿多点波峰,但是我们下次选择是偶数位,是负贡献,所以想让它尽量小,所以在知道后面还有波峰的情况下,我们就再选一个a[\(x{_2}\)],然后再选a[\(x{_3}\)]。这个时候就比只选a[\(x{_1}\)]更赚了。同理,我们后面还会继续选a[\(x{_4}\)]、a[\(x{_5}\)]、a[\(x{_6}\)]、a[\(x{_7}\)]。注意最后一个a[n]大可不必选了,因为后面再没有波峰,选了白减去一个数。

所以问题就变成了求波峰波谷的问题,我们只需要将每一次的波峰之和减去波谷之和即是答案(除去边界两点)。

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define endl '\n'
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 3e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;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 - '0', ch = getchar();return x*f; }
int dir[3] = { -1, 0, 1 }; ll a[maxn];
ll ans = 0;
ll n,q; void check(int pos)
{
if(pos>n||pos<1) return;
if(a[pos]>a[pos-1]&&a[pos]>a[pos+1]) ans += a[pos];
if(a[pos]<a[pos-1]&&a[pos]<a[pos+1]) ans -= a[pos];
} void Delete(int pos)
{
if(pos>n||pos<1) return;
if(a[pos]>a[pos-1]&&a[pos]>a[pos+1]) ans -= a[pos];
if(a[pos]<a[pos-1]&&a[pos]<a[pos+1]) ans += a[pos];
} int main()
{
int kase;
cin>>kase;
while(kase--)
{
n = read(), q = read(), ans = 0;
a[0] = a[n+1] = 0;
rep(i,1,n) a[i] = read();
rep(i,1,n) check(i);
cout<<ans<<endl;
rep(i,1,q)
{
ll l = read(), r = read();
map<int,int> Map;
rep(j,0,2) if(!Map[l+dir[j]]) Map[l+dir[j]] = 1, Delete(l+dir[j]);
rep(j,0,2) if(!Map[r+dir[j]]) Map[r+dir[j]] = 1, Delete(r+dir[j]);
Map.clear();
swap(a[l], a[r]);
rep(j,0,2) if(!Map[l+dir[j]]) Map[l+dir[j]] = 1, check(l+dir[j]);
rep(j,0,2) if(!Map[r+dir[j]]) Map[r+dir[j]] = 1, check(r+dir[j]);
cout<<ans<<endl;
}
}
return 0;
}

C2. Pokémon Army (hard version) CF #672的更多相关文章

  1. C2. Pokémon Army (hard version) 解析(思維)

    Codeforce 1420 C2. Pokémon Army (hard version) 解析(思維) 今天我們來看看CF1420C2 題目連結 題目 略,請直接看原題. 前言 根本想不到這個等價 ...

  2. C1. Pokémon Army (easy version) 解析(DP)

    Codeforce 1420 C1. Pokémon Army (easy version) 解析(DP) 今天我們來看看CF1420C1 題目連結 題目 對於一個數列\(a\),選若干個數字,求al ...

  3. Codeforces Round #672 (Div. 2) C1. Pokémon Army (easy version) (DP)

    题意:给你一组数\(a\),构造一个它的子序列\(b\),然后再求\(b_1-b2+b3-b4...\),问构造后的结果最大是多少. 题解:线性DP.我们用\(dp1[i]\)来表示在\(i\)位置, ...

  4. Pokémon Army (easy version) CodeForces - 1420C1 dp

    题意: 给你一个长度为n个序列v,你需要从中找一个子序列.这个子序列的值等于:子序列中奇数下标的值-偶数下标的值 你需要使得这个值尽可能大,让你输出这个最大值 题解: dp[i][0]表示:在原序列从 ...

  5. Codeforces Round #555 (Div. 3) C2. Increasing Subsequence (hard version)【模拟】

    一 题面 C2. Increasing Subsequence (hard version) 二 分析 需要思考清楚再写的一个题目,不能一看题目就上手,容易写错. 分以下几种情况: 1 左右两端数都小 ...

  6. CF 672 div2 D

    http://codeforces.com/contest/672/problem/D 题目大意: 有n个人,每个人有pi的钱,然后可以由如下操作,每次都可以挑选一个最富有的人,把它的钱给最穷的人.但 ...

  7. Codeforces Round #555 (Div. 3) C2. Increasing Subsequence (hard version) (贪心)

    题意:给你一组数,每次可以选队首或队尾的数放入栈中,栈中元素必须保持严格单增,问栈中最多能有多少元素,并输出选择情况. 题解:首先考虑队首和队尾元素不相等的情况,如果两个数都大于栈顶元素,那么我们选小 ...

  8. Codeforces Round #658 (Div. 2) C2. Prefix Flip (Hard Version) (构造)

    题意:给你两个长度为\(n\)的01串\(s\)和\(t\),可以选择\(s\)的前几位,取反然后反转,保证\(s\)总能通过不超过\(2n\)的操作得到\(t\),输出变换总数,和每次变换的位置. ...

  9. Codeforces Round #672 (Div. 2)

    比赛链接:https://codeforces.com/contest/1420 A. Cubes Sorting 题意 给出一个大小为 $n$ 的数组 $a$,每次只可以交换相邻的两个元素,最多交换 ...

  10. Codeforces Round #672 (Div. 2) A - C1题解

    [Codeforces Round #672 (Div. 2) A - C1 ] 题目链接# A. Cubes Sorting 思路: " If Wheatley needs more th ...

随机推荐

  1. JAVA stream集合List<Map>转二维集合Map<String,Map<String,Object>>

    简介 将一个 List<Map> 转换为一个二维的 Map 结构通常意味着我们需要创建一个 Map<K, Map<K, V>>.这里,外部的 Map 使用某个键(比 ...

  2. nginx代理静态页面添加二级目录

    location /wash { # root html; alias /home/cxq/wash-html/dist; index index.html index.htm; try_files ...

  3. 揭秘AI自动化框架Browser-use(终):利用MCP与Spring AI,3行代码复刻Browser-use实现

    技术背景与目标 在前几篇文章中,我们深入解析了Browser-use框架的核心机制,包括DOM树遍历与分析.提示词构造.任务分解与规划.以及浏览器操作的函数调用.我们将通过Spring AI和Play ...

  4. django笔记(3)-数据库操作

    一:路由系统    url    1.url(r'^index/', views.index),url(r'^home/',views.Home.as_view()), 一个url对应一个函数或一个类 ...

  5. Seata源码—1.Seata分布式事务的模式简介

    大纲 1.Seata分布式事务框架简介 2.Seata AT模式实现分布式事务的机制 3.Seata AT模式下的写隔离机制 4.Seata AT模式下的读隔离机制 5.官网示例说明Seata AT模 ...

  6. 鸿蒙next 定位开发全场景实践

    一.开场白 在智能设备普及的今天,位置服务已成为移动应用的基础设施.无论是外卖配送的实时轨迹追踪.导航应用的路径规划,还是运动健康类App的卡路里计算,精准的位置定位都是用户体验的关键支撑.鸿蒙nex ...

  7. Qt图像处理技术七:轮廓提取

    Qt图像处理技术七:轮廓提取 效果图 原理 图像先二值化让rgb数值相同,只有(0,0,0)或者(255,255,255) 取每个点的周围8个点,如果周围8个点与该点rgb值相同,则需要将该点描黑为( ...

  8. FileChooser文件保存样例

    FileChooser fc = new FileChooser();fc.setTitle("请选择文件保存位置");fc.setInitialDirectory($原始文件位置 ...

  9. Linux命令之Telnet的使用方法

    无论是linux还是windows,在命令行下,telnet命令都可以用于查看某个远端主机端口或者服务域名是否可以访问,语法糖如下: telnet IP 端口 telnet 域名 端口(即:telne ...

  10. @FeignClient注解自定义接口超时时间

    问题描述   每个微服务都有统一的接口超时时间设定,但也存在一些特殊的业务场景,其接口需要较长的超时时间,比如:导出excel报表.上传文件.拉取业务报表数据等等.此时,默认的超时设置就不能满足需求, ...