CF1175F The Number of Subpermutations
题意
给出一个长度为\(n\)的序列\(a\),问有多少个区间\([l,r]\)满足:在区间\([l,r]\)内,\([1,r-l+1]\)的每个整数都恰好出现了一次。
\(n \le 3 \times 10 ^ 5\),\(a_i \le n\)
思路
可以发现,其实最后的答案一定不会很大。
所以:暴力出奇迹!!!
先对题意进行小小的转化,题目等价于问有多少个区间\([l,r]\)满足以下两个条件:
1.区间\([l,r]\)中的每个数字都只在区间\([l,r]\)中出现了一遍
2.\(max\{a_l,a_{l+1}...a_r\}=r-l + 1\)
首先只考虑条件一
从后往前扫这个序列。用\(nxt_i\)表示在满足每个数字只出现一遍的前提下,以i为左端,右端点最靠右的位置。(感性理解,我也不知道该咋表述了233.)换句话说,就是\([i,nxt_i - 1]\)这个区间是满足条件的,而\([i,nxt_i]\)是不满足条件的。用\(pos_i\)表示i这个数字上次出现的位置。那么就有\(nxt_i = min(nxt_{i+1},pos[a_i])\)
在上面的基础上,找满足第二个条件的区间
在当前区间左端点为l的情况下,右端点可以是\([l,nxt_l-1]\)。
直接枚举肯定爆炸。
从左到右枚举右端点r,
当找到满足条件的区间时,就把答案加上1。然后继续枚举
如果当前枚举的区间不符合条件时,也就是说\(l+max\{a_l,a_{l+1}...a_r\} > r\)时。那么从r到\(l+max\{a_l,a_{l+1}...a_r\}\)肯定也是不满足条件的,所以直接把\(r\)调到\(l+max\{a_l,a_{l+1}...a_r\}\)就行了。
然后就可以跑过去这道题了(似乎还蛮快的233)。
代码
/*
* @Author: wxyww
* @Date: 2019-06-06 15:53:44
* @Last Modified time: 2019-06-06 16:36:31
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 300000 + 100;
ll read() {
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
int tree[N << 2];
int a[N];
void build(int rt,int l,int r) {
if(l == r) {
tree[rt] = a[l];return;
}
int mid = (l + r) >> 1;
build(rt << 1,l,mid);
build(rt << 1 | 1,mid + 1,r);
tree[rt] = max(tree[rt << 1],tree[rt << 1 | 1]);
}
int query(int rt,int l,int r,int L,int R) {
if(L <= l && R >= r) return tree[rt];
int mid = (l + r) >> 1;
int ret = 0;
if(L <= mid) ret = max(ret,query(rt << 1,l,mid,L,R));
if(R > mid) ret = max(ret,query(rt << 1 | 1,mid + 1,r,L,R));
return ret;
}
int nxt[N],pos[N],n;
int main() {
n = read();
for(int i = 1;i <= n;++i) a[i] = read(),pos[i] = n + 1;
build(1,1,n);
int ans = 0;
nxt[n + 1] = n + 1;
for(int i = n;i >= 1;--i) {
nxt[i] = min(pos[a[i]],nxt[i + 1]);
pos[a[i]] = i;
for(int j = i;j < nxt[i];++j) {
int x = query(1,1,n,i,j);
if(i + x - 1 > j) j = i + x - 2;else ++ans;
}
}
cout<<ans;
return 0;
}
CF1175F The Number of Subpermutations的更多相关文章
- Codeforces 1175F The Number of Subpermutations
做法①:RMQ(预处理NLOGN+后续跳跃蜜汁复杂度) 满足题意的区间的条件转换: 1.长度为R-L+1则最大值也为R-L+1 2.区间内的数不重复 当RMQ(L,R)!=R-L+1时 因为已经保证了 ...
- Codeforces 1175F The Number of Subpermutations (思维+rmq)
题意: 求区间[l, r]是一个1~r-l+1的排列的区间个数 n<=3e5 思路: 如果[l,r]是一个排列,首先这里面的数应该各不相同,然后max(l,r)应该等于r-l+1,这就能唯一确定 ...
- Codeforces 1175F - The Number of Subpermutations(线段树+单调栈+双针/分治+启发式优化)
Codeforces 题面传送门 & 洛谷题面传送门 由于这场的 G 是道毒瘤题,蒟蒻切不动就只好来把这场的 F 水掉了 看到这样的设问没人想到这道题吗?那我就来发篇线段树+单调栈的做法. 首 ...
- JavaScript Math和Number对象
目录 1. Math 对象:数学对象,提供对数据的数学计算.如:获取绝对值.向上取整等.无构造函数,无法被初始化,只提供静态属性和方法. 2. Number 对象 :Js中提供数字的对象.包含整数.浮 ...
- Harmonic Number(调和级数+欧拉常数)
题意:求f(n)=1/1+1/2+1/3+1/4-1/n (1 ≤ n ≤ 108).,精确到10-8 (原题在文末) 知识点: 调和级数(即f(n))至今没有一个完全正确的公式, ...
- Java 特定规则排序-LeetCode 179 Largest Number
Given a list of non negative integers, arrange them such that they form the largest number. For exam ...
- Eclipse "Unable to install breakpoint due to missing line number attributes..."
Eclipse 无法找到 该 断点,原因是编译时,字节码改变了,导致eclipse无法读取对应的行了 1.ANT编译的class Eclipse不认,因为eclipse也会编译class.怎么让它们统 ...
- 移除HTML5 input在type="number"时的上下小箭头
/*移除HTML5 input在type="number"时的上下小箭头*/ input::-webkit-outer-spin-button, input::-webkit-in ...
- iOS---The maximum number of apps for free development profiles has been reached.
真机调试免费App ID出现的问题The maximum number of apps for free development profiles has been reached.免费应用程序调试最 ...
随机推荐
- 记录一个终端入网小助手的bug
背景:技术leader拿到一台超薄笔记本,系统标准化安装,笔记本一开机风扇嗡嗡响,键盘也开始发烫,资源占用排名前三的进程都是终端管理软件,一下子就找上门了.处理:进程分析发现异常,卸载入网小助手后恢复 ...
- kafka中消费者消费消息之每个线程维护一个KafkaConsumer实例
1.首先启动自己的kafka集群哟. 启动zk: bin/zkServer.sh start conf/zoo.cfg. 验证zk是否启动成功: bin/zkServer.sh status conf ...
- easyui 扩展 datagrid 数据网格视图
效果如图: js代码: $("#tdg").datagrid({ width: 200, url: "/Laboratory/ ...
- C# - VS2019 WinFrm程序调用ZXing.NET实现条码、二维码和带有Logo的二维码的识别
前言 C# WinFrm程序调用ZXing.NET实现条码.二维码和带有Logo的二维码的识别. ZXing.NET导入 GitHub开源库 ZXing.NET开源库githib下载地址:https: ...
- curl tftp libcurl 功能使用
#include <curl/curl.h> static size_t read_callback(void *ptr, size_t size, size_t nmemb, void ...
- afnet缓存
http://www.open-open.com/code/view/1432299750333
- 【已采纳】新项目第一次怎么上传到github里面
言归正传,最近学习了怎么将新创建的本地代码上传到github上,这里简单的记录一下,我喜欢使用命令行,这里全用命令行来实现,不了解git命令的可以去了解下. 第一步:建立git仓库 cd到你的本地 ...
- 互联网渗透测试之Wireshark的高级应用
互联网渗透测试之Wireshark的高级应用 1.1说明 在本节将介绍Wireshark的一些高级特性 1.2. "Follow TCP Stream" 如果你处理TCP协议,想要 ...
- xshell 远程登陆CentOS7 免密登陆
首先说一下大体的思路: 1. 以密码登陆CentOS系统 2. 配置ssh 3. xshell 生成秘钥 4. 进行免密登陆 软件.设备: xshell(下载地址(免费版),也可以自行百度下载) Ce ...
- (八)OpenStack---M版---双节点搭建---Cinder安装和配置
↓↓↓↓↓↓↓↓视频已上线B站↓↓↓↓↓↓↓↓ >>>>>>传送门 1.创建数据库并授权 2.获得admin凭证执行管理员命令并创建服务证书 3.创建块存储设备AP ...