CF1167E. Range Deleting
题意
给定长度为\(n\)的数组\(a\),其中任意\(a_i \leq x\)
定义\(f(l,r)\)为删除\(a\)中值域在\([l,r]\)的数后剩余的数组.
统计满足\(1\leq l \leq r \leq x\)且\(f(l,r)\)是非严格不下降序列的数对\((l,r)\)的数量。
题解
首先想想就可以发现这个\(l\)和\(r\)是有单调性的。那思路就可以往双指针/二分那边靠一下。
现在的问题就是怎么做到\(O(1)\)或者\(O(\log n)\) 判断删除一段区间后的序列是否合法。
把最后的序列拆成两段:权值在\((1,l-1)\)和权值在\((r+1,x)\)的。
发现只需要\((1,l-1)\)这段满足按权值排序后下标单调上升,\((r+1,x)\)这段同理,并且\(l-1\)的下标比\(r+1\)的下标小。
那么这个东西其实是可以预处理出来的。
考虑处理出\(posmax\)和\(posmin\)表示数字\(i\)出现的最小下标和最大下标,\(premax\)和\(sufmin\)表示按权值排序后\(1-i\)的最大下标 和 按权值排序后\(i-x\)的最小下标。
依靠上面预处理出来的数据我们就可以再处理出一个\(precan\)和\(sufcan\)表示\((1,i)\)是否合法以及\((i,x)\)是否合法,那么就可以\(O(1)\)判断删除一段区间后的序列是否合法了。
使用双指针就可以做到\(O(n)\)解决。
#include <bits/stdc++.h>
using namespace std;
namespace io {
char buf[1<<21], *p1 = buf, *p2 = buf;
inline char gc() {
if(p1 != p2) return *p1++;
p1 = buf;
p2 = p1 + fread(buf, 1, 1 << 21, stdin);
return p1 == p2 ? EOF : *p1++;
}
#define G gc
#ifndef ONLINE_JUDGE
#undef G
#define G getchar
#endif
template<class I>
inline void read(I &x) {
x = 0; I f = 1; char c = G();
while(c < '0' || c > '9') {if(c == '-') f = -1; c = G(); }
while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = G(); }
x *= f;
}
template<class I>
inline void write(I x) {
if(x == 0) {putchar('0'); return;}
I tmp = x > 0 ? x : -x;
if(x < 0) putchar('-');
int cnt = 0;
while(tmp > 0) {
buf[cnt++] = tmp % 10 + '0';
tmp /= 10;
}
while(cnt > 0) putchar(buf[--cnt]);
}
#define in(x) read(x)
#define outn(x) write(x), putchar('\n')
#define out(x) write(x), putchar(' ')
} using namespace io;
#define ll long long
const int N = 1000100;
const int inf = 1e9;
int n, x;
int a[N];
int posmn[N], posmx[N];
//每个大小的数的最左端点和最右端点
int sufmn[N], premx[N];
//从大到小/从小到大的max和min位置
bool sufcan[N], precan[N];
//保留i到x这段是否合法,保留1到i这段是否合法
bool check(int l, int r) {
if(!precan[l - 1]) return false;
if(!sufcan[r + 1]) return false;
if(sufmn[r + 1] < premx[l - 1]) return false;
return true;
}
int main() {
read(n); read(x);
memset(posmn, 0x3f, sizeof(posmn));
for(int i = 1; i <= n; ++i) read(a[i]);
for(int i = 1; i <= n; ++i) {
posmn[a[i]] = min(posmn[a[i]], i);
posmx[a[i]] = max(posmx[a[i]], i);
}
sufmn[x + 1] = inf;
for(int i = 1; i <= x; ++i) premx[i] = max(premx[i - 1], posmx[i]);
for(int i = x; i; --i) sufmn[i] = min(sufmn[i + 1], posmn[i]);
sufcan[x + 1] = precan[0] = true;
for(int i = 1; i <= x; ++i) precan[i] = precan[i - 1] && (premx[i - 1] < posmn[i]);
for(int i = x; i; --i) sufcan[i] = sufcan[i + 1] && (posmx[i] < sufmn[i + 1]);
ll sum = 0;
int l = 1, r = 1;
for(; l <= x; ++l) {
if(l > r) ++r;
while(r < x && !check(l, r)) ++r;
if(check(l, r)) sum += x - r + 1;
}
outn(sum);
return 0;
}
CF1167E. Range Deleting的更多相关文章
- Codeforces 1167 E Range Deleting 双指针+思维
题意 给一个数列\(a\),定义\(f(l,r)\)为删除\(a\)中所有满足\(l<=a_i<=r\)的数后的数列,问有多少对\((l,r)\),使\(f(l,r)\)是一个 ...
- Educational Codeforces Round 65 (Rated for Div. 2) E. Range Deleting(思维+coding)
传送门 参考资料: [1]:https://blog.csdn.net/weixin_43262291/article/details/90271693 题意: 给你一个包含 n 个数的序列 a,并且 ...
- 1167E - Range Deleting 双指针
题意:给出n个数的序列,并给出x,这n个数的范围为[1,x],f(L,R)表示删除序列中取值为[l,r]的数,问有几对L,R使得操作后的序列为非递减序列 思路:若[l,r]成立,那么[l,r+1],. ...
- Educational Codeforces Round 65 (Rated for Div. 2)题解
Educational Codeforces Round 65 (Rated for Div. 2)题解 题目链接 A. Telephone Number 水题,代码如下: Code #include ...
- [ Educational Codeforces Round 65 (Rated for Div. 2)][二分]
https://codeforc.es/contest/1167/problem/E E. Range Deleting time limit per test 2 seconds memory li ...
- codeforces Educational Codeforces Round 65 (补完)
C News Distribution 并查集水题 D Bicolored RBS 括号匹配问题,如果给出的括号序列nesting depth为n,那么最终可以分成两个nesting depth为n ...
- Educational Codeforces Round 65 E,F
E. Range Deleting 题意:给出一个序列,定义一个操作f(x,y)为删除序列中所有在[x,y]区间内的数.问能使剩下的数单调不减的操作f(x,y)的方案数是多少. 解法:不会做,思维跟不 ...
- Educational Codeforces Round 65 选做
好久没更博客了,随便水一篇 E. Range Deleting 题意 给你一个长度为 \(n\) 的序列 \(a_1,a_2,\dots a_n\) ,定义 \(f(l,r)\) 为删除 \(l\le ...
- Codeforces Edu Round 65 A-E
A. Telephone Number 跟之前有一道必胜策略是一样的,\(n - 10\)位之前的数存在\(8\)即可. #include <iostream> #include < ...
随机推荐
- [转帖]在 k8s 中自动为域名配置 https
在 k8s 中自动为域名配置 https https://juejin.im/post/5db8d94be51d4529f73e2833 随着 web 的发展,https 对于现代网站来说是必不可少的 ...
- 【计算机网络基础】URI、URN和URL的区别
先引用一张关系图 灰色部分为URI URI强调的是给资源标记命名,URL强调的是给资源定位. URI是Uniform Resource Identifier,表示是一个资源: URL是Uniform ...
- day40——数据库、数据库分类、安装、修改密码、字符集编码、简单语句介绍
day40 详情请看:https://www.cnblogs.com/clschao/articles/9907529.html 数据库 数据库 简而言之可视为电子化的文件柜--存储电子文件的处所,用 ...
- lmir 随笔
近期需要研究一些特征工程的工作,就打算把微软之前公布出来的特征都复现一遍,今天遇到的特征是 LMIR, 其实也就是language model for information retrieval的简写 ...
- 从docker中备份oracle和mongo数据
从docker中导出Oracle数据 这里推荐先把脚本文件放到容器里面(这里没有) #!/bin/sh # 进入容器 # 本机备份位置 /root/oracleData/dist/temp # 当前日 ...
- tidb测试环境搭建
tidb ansible 部署方式环境检查过于严格,测试环境往往达不到标准,需调整一些参数才能部署成功. 基于tidb2.0版本需要调整的参数 [tidb@ansible01 tidb-ansible ...
- python爬虫-《笔趣看》网小说《悟空看私聊》
小编是个爱看小说的人,哈哈 # -*- coding:UTF-8 -*- ''' 类说明:下载<笔趣看>网小说<悟空看私聊> ''' from bs4 import Beaut ...
- Python中logging快速上手教程
本文使用得日志需要导入logging模块和logging.handlers模块,即 import logging import logging.handlers ''' author = " ...
- 记录:拷贝gitblit里的项目使用git命令clone、pull、push等,出现一直在加载,卡住没反应的问题
俺想克隆别人gitblit里的其中一个版本库(俺在别人gitblit有权限) 懂得git的道友们,都应该知道克隆一个公共项目,随便找到,打开git终端,输入git clone 项目地址就行了 到了俺这 ...
- 玩转Spring全家桶笔记 03 Spring的JDBC操作以及SQL批处理的实现
1 spring-jdbc core JdbcTemplate 等相关核心接口和类(核心) datesource 数据源相关的辅助类(内嵌数据源的初始化) object 将基本的JDBC操作封装成对象 ...