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 < ...
随机推荐
- socket支持ipv6
转自:https://www.jianshu.com/p/9926b99a7fef 以前cocos2d-x的项目里都使用的是libwebsocket,如果想支持ipv6,只需要升级相应的库即可,现在有 ...
- 10分钟弄懂Raft算法
分布式系统在极大提高可用性.容错性的同时,带来了一致性问题(CAP理论).Raft算法能够解决分布式系统环境下的一致性问题. 我们熟悉的ETCD注册中心就采用了这个算法:你现在看的这篇微信公众号文章, ...
- vuex 的基本使用
工程目录 主要关注store 文件夹下的文件 store/index.js import Vue from 'vue' import Vuex from 'vuex' // import getter ...
- 百度地图jsapi 自定义大头针的方法
百度地图jsapi 自定义大头针的方法<pre> var myIcon = new BMap.Icon("http://developer.baidu.com/map/jsdem ...
- php_mvc实现步骤三,四
3.match_mvc MVC 以ecshop的前台为例: 功能一: 首页 购物车数据,商品分类数据,其他的首页需要的数据 功能二: 拍卖活动 购物车数据,商品分类数据,拍卖相关数据 功能三: 团购商 ...
- Windows网络命令的相关指令(1)
1.Ipconfig 该命令可以检查网络接口配置.如果用户系统不能到达远程主机,而同一系统的其他主机可以到达,那么用该命令对这种故障进行判断是有必要的.当主机能到达远程主机但不能到达本网主机时,则表示 ...
- 【LeetCode】最长回文子串【动态规划或中心扩展】
给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad"输出: "bab"注意: " ...
- InfoGan笔记
InfoGAN: Interpretable Representation Learning by Information Maximizing Generative Adversarial Nets ...
- 【LEETCODE】47、985. Sum of Even Numbers After Queries
package y2019.Algorithm.array; /** * @ProjectName: cutter-point * @Package: y2019.Algorithm.array * ...
- Python Paramiko实现sftp文件上传下载以及远程执行命令
一.简介 Paramiko模块是基于Python实现的SSH远程安全连接,用于SSH远程执行命令.文件传输等功能. 安装模块 默认Python没有自带,需要手动安装: pip3 install par ...