Educational Codeforces Round 39 (Rated for Div. 2) G

题意:

给一个序列\(a_i(1 <= a_i <= 10^{9}),2 <= n <= 200000\), 如果至多删除其中的一个数之后该序列为严格上升序列,那么称原序列为几乎严格上升序列。

现在每次将序列中的任意数字变成任意数字,问最少要操作几次才能将序列变成几乎严格上升子序列。

思路:

如果不考虑删除,求让整个序列都变成严格上升子序列的次数

求出\(序列a_i - i\)的最长不下降子序列的长度\(len\), \(n - len\)就是答案

现在来考虑删除一个数的情况

我们枚举删除第\(k\)个数 前面的数做变换\(a_i - i (i < k)\), 后面的数做变换\(a_i - (i-1) (i > k)\)

我们计算以k-1结尾的最长不下降子序列和后面某个\(a_j(a_j >= a_{k-1})\)起始的最长不下降子序列拼接起来得到的长度,更新答案即可

先离散化处理

维护以\(a_i\)结尾的的最长不下降子序列的长度和以\(a_i\)开始的最长不下降子序列的长度

假设先从后往前处理,可以处理出后缀,同时也可以计算出每个数要拼接的最长后缀的长度,再从前往后处理算出前缀,更新答案即可。

用线段树维护 复杂度\(O(nlogn)\)

#include<bits/stdc++.h>
#define LL long long
#define P pair<int,int>
using namespace std;
const int N = 4e5 + 10;
int a[N];
vector<int> b;
int n,nn;
int dppre[N],dpsuf[N],sufmx[N];
int mx[N << 2];
void update(int pos,int val,int l,int r,int rt){
if(l == r){
mx[rt] = max(mx[rt],val);
return ;
}
int m = l + r >> 1;
if(pos <= m) update(pos,val,l,m,rt<<1);
else update(pos,val,m+1,r,rt<<1|1);
mx[rt] = max(mx[rt << 1], mx[rt << 1|1]);
}
int querymx(int L,int R,int l,int r,int rt){
if(L <= l && R >= r) return mx[rt];
int ans = 0;
int m = l + r>>1;
if(L <= m) ans = max(ans, querymx(L, R, l, m, rt<<1));
if(R > m) ans = max(ans, querymx(L, R, m + 1, r, rt<<1|1));
return ans;
}
/*
10
5 6 7 8 9 5 10 11 12 13
*/
int main(){ cin>>n;
for(int i = 1;i <= n;i++){
scanf("%d",a + i);
b.push_back(a[i] - i);
b.push_back(a[i] - i + 1);
}
sort(b.begin(), b.end());
b.erase(unique(b.begin(),b.end()),b.end());
nn = b.size();
for(int i = n;i >= 1;i--){
int pos = lower_bound(b.begin(), b.end(), a[i-1] - i+1) - b.begin() + 1;
if(i == 1) pos = 1;
sufmx[i-1] = querymx(pos, nn, 1, nn, 1);
pos = lower_bound(b.begin(), b.end(), a[i] - i + 1) - b.begin() + 1;
int v = querymx(pos, nn, 1, nn, 1);
dpsuf[i] = v + 1;
update(pos, dpsuf[i], 1, nn, 1);
//cout<<i - 1<<" "<<sufmx[i - 1]<<" "<<v + 1<<endl;
}
for(int i = 1;i <= (nn<<2);i++){
mx[i] = 0;
}
int ans = sufmx[0];
for(int i = 1;i <= n;i++){
int pos = lower_bound(b.begin(), b.end(), a[i] - i) - b.begin() + 1;
int v = querymx(1, pos, 1, nn, 1);
dppre[i] = v + 1;
ans = max(dppre[i] + sufmx[i], ans);
//cout<<i<<" "<<dppre[i]<<" "<<sufmx[i]<<endl;
update(pos, dppre[i], 1, nn, 1);
}
cout<<max(0,n - 1 - ans)<<endl;
return 0;
}

Educational Codeforces Round 39 (Rated for Div. 2) G的更多相关文章

  1. #分组背包 Educational Codeforces Round 39 (Rated for Div. 2) D. Timetable

    2018-03-11 http://codeforces.com/contest/946/problem/D D. Timetable time limit per test 2 seconds me ...

  2. Educational Codeforces Round 39 (Rated for Div. 2) 946E E. Largest Beautiful Number

    题: OvO http://codeforces.com/contest/946/problem/E CF 946E 解: 记读入串为 s ,答案串为 ans,记读入串长度为 len,下标从 1 开始 ...

  3. Educational Codeforces Round 39 (Rated for Div. 2) B. Weird Subtraction Process[数论/欧几里得算法]

    https://zh.wikipedia.org/wiki/%E8%BC%BE%E8%BD%89%E7%9B%B8%E9%99%A4%E6%B3%95 取模也是一样的,就当多减几次. 在欧几里得最初的 ...

  4. codeforces Educational Codeforces Round 39 (Rated for Div. 2) D

    D. Timetable time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  5. Educational Codeforces Round 58 (Rated for Div. 2) G 线性基

    https://codeforces.com/contest/1101/problem/G 题意 一个有n个数字的数组a[],将区间分成尽可能多段,使得段之间的相互组合异或和不等于零 题解 根据线性基 ...

  6. Educational Codeforces Round 53 (Rated for Div. 2)G. Yet Another LCP Problem

    题意:给串s,每次询问k个数a,l个数b,问a和b作为后缀的lcp的综合 题解:和bzoj3879类似,反向sam日神仙...lcp就是fail树上的lca.把点抠出来建虚树,然后在上面dp即可.(感 ...

  7. Educational Codeforces Round 51 (Rated for Div. 2) G. Distinctification(线段树合并 + 并查集)

    题意 给出一个长度为 \(n\) 序列 , 每个位置有 \(a_i , b_i\) 两个参数 , \(b_i\) 互不相同 ,你可以进行任意次如下的两种操作 : 若存在 \(j \not = i\) ...

  8. Educational Codeforces Round 48 (Rated for Div. 2)G. Appropriate Team

    题意:求满足条件的(i,j)对数:\(gcd(v,a_i)=x,lcm(v,a_j)=y\) 题解:\(x|a_i,a_j|y\),\(x|y\),考虑质因子p,假设a_i中p次数为a,x中次数为b, ...

  9. Educational Codeforces Round 47 (Rated for Div. 2)G. Allowed Letters 网络流

    题意:给你一个字符串,和每个位置可能的字符(没有就可以放任意字符)要求一个排列使得每个位置的字符在可能的字符中,求字典序最小的那个 题解:很容易判断有没有解,建6个点表示从a-f,和源点连边,容量为原 ...

随机推荐

  1. JDK1.8改为JDK1.7过程

    电脑之前eclipse版本要求JDK1.8版本,现在要用jboss7.1做性能测试,目前仅支持JDK7.故需要降级. 网上有很多说把1.8删掉,这种做法我是不建议的,那么要用的时候呢?又得装回来多蛋疼 ...

  2. Python对象引用问题总结

    对于对象引用问题,一直是一知半解的状态,现整理以备使用. 操作不可变对象进行加减运算时,会在内存中创建新的不可变实例,不会影响原来的引用>>> c=12>>> d= ...

  3. Qt官方开发环境生成的exe发布方式

    本来想自己写一个打包程序的文章了,但是我发现了宝贝,在这里,大神写的比我牛逼的多了,这里做一下搬运工 一是为了方便大家 二是为了以后方便自己找 原文链接:http://tieba.baidu.com/ ...

  4. 【SpringCloud】 第十篇: 高可用的服务注册中心

    前言: 必需学会SpringBoot基础知识 简介: spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选. ...

  5. vivado使用感想

    寒假学了一学期vivado也没有学出什么名堂:为了调试龙芯的五级流水CPU,今天肝了一下午结果还把vivado给摸清楚了,果然是以目标为导向最能出成绩. vivado开发硬件的流程 写代码 模拟仿真s ...

  6. POJ 2104 K-th Number(划分树)

    Description You are working for Macrohard company in data structures department. After failing your ...

  7. 20162328蔡文琛week01

    学号20162328 <程序设计与数据结构>第1周学习总结 教材学习内容总结 通过练习课本上给出的代码并结合老师所提供教程,熟悉并初步了解Java的基本编辑 教材学习中的问题和解决过程 无 ...

  8. PMS

    "通讯录--PMS"功能介绍及界面展示 首先是我们的登陆界面,以绿色为基调,配以繁星组成的星阵图,寓意为"散是满天星",希望每一位同学能在各自的生活中闪耀. 当 ...

  9. 《剑指offer》---顺时针打印矩阵

    本文算法使用python3实现 1. 问题1 1.1 题目描述:   输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 ...

  10. 华为oj----iNOC产品部-杨辉三角的变形 .

    此题提供三种方法,第一种,一开始就能想到的,设置一个足够大的数组存储生成的杨辉三角,然后进行判断就行,此方法参见:华为oj iNOC产品部-杨辉三角的变形 另一种方法是采用递归: 三角形的每行的个数为 ...