博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cf 1167 E Range Deleting
阅读量:4332 次
发布时间:2019-06-06

本文共 1332 字,大约阅读时间需要 4 分钟。

cf 1167 E.

题意

给出n个x范围的数,求删除范围在[L, R]的数,使得该序列成为一个非严格递增的序列,问有多少对数?(注空序列也算进答案,即[1,x]也是答案

题解

1.可以看出,如果删除[1, i]是符合题意的答案,那么[1, i+1] ~ [1, x]都是符合题意的答案。

2.如果[1, i]不是合法的,那么[2, i]也不可能是合法的。所以左右指针都只会往前移;

3.如果[L, R]是合法的,那么答案贡献是 x - R + 2;

判断区间[L, R]是否合法的:

[1, L-1]的数最靠后的位置 < [R + 1, x]的数最靠前的位置

下面继续捋一捋怎么写代码:

先找出最小的i,满足[1, i]是合法的。
把左指针往前移,如果[2, i]不合法,就把右指针往后移,直到合法!
如果i最靠前的位置 > [1, i - 1]最靠后的位置,说明左指针往后移也不可能出现合法的了。
#include 
#include
#include
using std::max;using std::min;int l[1000010], ll[1000010], r[1000010], rr[1000010];int main() { int n, x, a; scanf("%d %d", &n, &x); memset(l, 0x3f3f3f3f, sizeof(l)); memset(ll, 0x3f3f3f3f, sizeof(ll)); for(int i = 1; i <= n; i++) { scanf("%d", &a); l[a] = min(i, l[a]); r[a] = i; } for(int i = 1; i <= x; i++) { rr[i] = max(rr[i-1], r[i]);//rr记录[1, i]最靠后的位置 ll[x - i + 1] = min(l[x - i + 1], ll[x - i + 2]);//ll记录[i, x]最靠前的位置 } int R = x; long long ans = 0; while(ll[R] >= r[R-1] && R >= 1) R--;//算出最小的i for(int i = 0; i < x; i++) { if(i && l[i] < rr[i-1]) break;//i最靠前的位置>[1, i - 1]最靠后的位置 while(R <= i + 1 || rr[i] > ll[R]) R++;//右指针往后移,直到找到合法的区间, ans += x - R + 2; } printf("%lld\n", ans); return 0;}

转载于:https://www.cnblogs.com/fanshhh/p/11370669.html

你可能感兴趣的文章
NAS 创建大文件
查看>>
学习笔记-模块之xml文件处理
查看>>
接口测试用例
查看>>
面试:用 Java 实现一个 Singleton 模式
查看>>
Sybase IQ导出文件的几种方式
查看>>
案例:手动输入一个字符串,打散放进一个列表,小写字母反序 大写字母保持不变...
查看>>
linux 系统下 tar 的压缩与解压缩命令
查看>>
阿里负载均衡,配置中间证书问题(在starcom申请免费DV ssl)
查看>>
转:How to force a wordbreaker to be used in Sharepoint Search
查看>>
MySQL存储过程定时任务
查看>>
Python中and(逻辑与)计算法则
查看>>
POJ 3267 The Cow Lexicon(动态规划)
查看>>
设计原理+设计模式
查看>>
音视频处理
查看>>
tomcat 7服务器跨域问题解决
查看>>
前台实现ajax 需注意的地方
查看>>
Jenkins安装配置
查看>>
个人工作总结05(第二阶段)
查看>>
Java clone() 浅拷贝 深拷贝
查看>>
深入理解Java虚拟机&运行时数据区
查看>>