题意:给你一个序列,让你任意选出一个子序列,使得奇数位和减去偶数位和最大。同时有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. 测试工作中用到的MongoDB命令

    1.远程连接MongoDB mongo host:port/dbname (host和port根据自己需要修改) 连接成功页面如下: 2.显示所有数据库 show dbs 3.切换到oversea-a ...

  2. 🎀FreeMarker 禁止自动转义标签-noautoesc

    简介 FreeMarker 是一个用 Java 语言编写的模板引擎,它被设计用来生成文本输出(HTML 网页.电子邮件.配置文件等).在 FreeMarker 中,默认情况下,当你在模板中输出变量时, ...

  3. DPDI(Dispatch PDI)kettle调度管理平台环境部署升级

    1.DPDI演示环境 DPDI online登录域名:http://dpdi.pizzalord.site 用户名:dpdi 密 码:dpdi 2.DPDI下载 DPDI online部署包下载地址: ...

  4. App自动化的元素定位

    一.Appium定位步骤 打开appium,输入本地IP,点击启动服务器 1.点击启动检查器会话 2.配置所需功能,点击启动会话 二.App页面元素 App页面元素分为布局和控件两种 1.布局 Fra ...

  5. nodejs获取一个可用的端口,检查端口是否被占用(完美方案)

    nodejs检查端口是否被占用,先看个运行效果: E:\wamp64\www\tmpPro\tryuseport>node t.js 端口:8022被占用 端口:8023被占用 端口:8024可 ...

  6. thinkphphp 计算分页 和分页总数 和sql计算分页 php

    利用page计算分页 $p=input('p')?input('p'):1; $limit=6; $res=db('points_log')->where(['p_uid'=>$uid,' ...

  7. 1K star!这个开源项目让短信集成简单到离谱,开发效率直接翻倍!

    嗨,大家好,我是小华同学,关注我们获得"最新.最全.最优质"开源项目和高效工作学习方法 "让简单的事情回归简单的本质" -- SMS4J 项目宣言 SMS4J ...

  8. 字典(Dictionary) update()方法

    描述 python字典(Dictionary) update()函数吧dict2的键/值对更新到dict里 语法 dict.update(dict2) 参数 dict2 -- 添加到指定字典dict里 ...

  9. No grammar constraints (DTD or XML schema) detected for the document

    warning: No grammar constraints (DTD or XML schema) detected for the document 未检测到文档的语法约束(DTD或XML模式) ...

  10. 抽象类&&接口做形参(其实同理)

    抽象类:传入该抽象类的子类对象 eg: package javaBasic; public class TestAbstract { public static void main(String[] ...