题目链接

题意

给出一个长度为\(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的更多相关文章

  1. Codeforces 1175F The Number of Subpermutations

    做法①:RMQ(预处理NLOGN+后续跳跃蜜汁复杂度) 满足题意的区间的条件转换: 1.长度为R-L+1则最大值也为R-L+1 2.区间内的数不重复 当RMQ(L,R)!=R-L+1时 因为已经保证了 ...

  2. Codeforces 1175F The Number of Subpermutations (思维+rmq)

    题意: 求区间[l, r]是一个1~r-l+1的排列的区间个数 n<=3e5 思路: 如果[l,r]是一个排列,首先这里面的数应该各不相同,然后max(l,r)应该等于r-l+1,这就能唯一确定 ...

  3. Codeforces 1175F - The Number of Subpermutations(线段树+单调栈+双针/分治+启发式优化)

    Codeforces 题面传送门 & 洛谷题面传送门 由于这场的 G 是道毒瘤题,蒟蒻切不动就只好来把这场的 F 水掉了 看到这样的设问没人想到这道题吗?那我就来发篇线段树+单调栈的做法. 首 ...

  4. JavaScript Math和Number对象

    目录 1. Math 对象:数学对象,提供对数据的数学计算.如:获取绝对值.向上取整等.无构造函数,无法被初始化,只提供静态属性和方法. 2. Number 对象 :Js中提供数字的对象.包含整数.浮 ...

  5. Harmonic Number(调和级数+欧拉常数)

    题意:求f(n)=1/1+1/2+1/3+1/4-1/n   (1 ≤ n ≤ 108).,精确到10-8    (原题在文末) 知识点:      调和级数(即f(n))至今没有一个完全正确的公式, ...

  6. Java 特定规则排序-LeetCode 179 Largest Number

    Given a list of non negative integers, arrange them such that they form the largest number. For exam ...

  7. Eclipse "Unable to install breakpoint due to missing line number attributes..."

    Eclipse 无法找到 该 断点,原因是编译时,字节码改变了,导致eclipse无法读取对应的行了 1.ANT编译的class Eclipse不认,因为eclipse也会编译class.怎么让它们统 ...

  8. 移除HTML5 input在type="number"时的上下小箭头

    /*移除HTML5 input在type="number"时的上下小箭头*/ input::-webkit-outer-spin-button, input::-webkit-in ...

  9. 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.免费应用程序调试最 ...

随机推荐

  1. ThreadLocal 简单解析

    ThreadLocal 简单解析 基于jdk1.8 ThreadLocal一定不陌生,开发中常用,也是面试里的常客了,但是往往我们可能只是知道该类的作用.学习该类对于个人的多线程编码能力是大有裨益的, ...

  2. 物联网架构成长之路(33)-EMQ数据存储到influxDB

    一.前言 时隔一年半,技术变化特别快,学习也要跟上才行.以前写过EMQ数据转存问题,当时用了比较笨的方法,通过写插件的方式,把MQTT里面的数据发送到数据库进行存储.当时也是为了学习erlang和em ...

  3. Python连载33-共享变量加锁、释放

    一.共享变量 共享变量:当多个线程访问同一个变量的时候.会产生共享变量的问题. 例子: import threading sum = 0 loopSum = 1000000 def myAdd(): ...

  4. CentOS 7.6 安装htop

    yum -y install epel-release.noarch yum -y install htop htop 上面左上角显示CPU.内存.交换区的使用情况,右边显示任务.负载.开机时间,下面 ...

  5. SiftingAppender logback 动态 输出 日志 到指定日志文件

    SiftingAppender https://www.mkyong.com/logging/logback-different-log-file-for-each-thread/

  6. python time包中的time.time()和time.clock()的区别

    在统计python代码 执行速度时要使用到time包,在查找相关函数时有time.time()和time.clock()两个函数可供选择.而两者是有区别的: cpu 的运行机制:cpu是多任务的,例如 ...

  7. java 图书馆初级编写

    import java.util.Scanner; import java.util.Arrays; public class book { public static void main(Strin ...

  8. [b0011] windows 下 eclipse 开发 hdfs程序样例 (三)

    目的: 学习windows 开发hadoop程序的配置. [b0007] windows 下 eclipse 开发 hdfs程序样例 太麻烦 [b0010] windows 下 eclipse 开发 ...

  9. Django框架 --序列化组件(serializer)

    一 .Django自带序列化组件 Django内置的serializers(把对象序列化成json字符串) from django.core import serializers from djang ...

  10. openstack 创建实例报错 **aborted: Failed to allocate the network(s), not rescheduling

    消息 Build of instance 6320b5f2-edc2-4e8e-b07c-0047f7ed8f6a aborted: Failed to allocate the network(s) ...