做法①:RMQ(预处理NLOGN+后续跳跃蜜汁复杂度)

满足题意的区间的条件转换:

1.长度为R-L+1则最大值也为R-L+1

2.区间内的数不重复

当RMQ(L,R)!=R-L+1时 因为已经保证了 i~r[i] 之间的数不重复 则RMQ(L,R)必定大于当前的R-L+1 所以我们需要至少跳到 i+RMQ(L,R)-1

#include<bits/stdc++.h>
using namespace std;
int a[], r[];
int where[];
int dp[][];
int n,ans;
void rmqinit() {
for (int i = ; i <= n; i++) {
dp[i][] = a[i];
}
for (int j = ; ( << j) <= n; j++) {
for (int i = ; i + ( << j) - <= n; i++) {
dp[i][j] = max(dp[i][j - ], dp[i + ( << (j - ))][j - ]);
}
}
}
int rmq(int l, int r) {
int x = ;
while ( << (x + ) <= r - l + ) {
x++;
}
return max(dp[l][x], dp[r - ( << x) + ][x]);
}
int main() {
cin >> n;
r[n] = n;
for (int i = ; i <= n; i++) {
cin >> a[i];
}
rmqinit();
where[a[n]] = n;
for (int i = n - ; i >= ; i--) {
if (where[a[i]]) {
r[i] = min(r[i + ], where[a[i]] - );
} else {
r[i] = r[i + ];
}
where[a[i]] = i;
}
for(int i=;i<=n;i++)
{
int j=i;
while(j<=r[i])
{
if(rmq(i,j)==j-i+)
{
ans++;
j++;
}
else
{
j=i+rmq(i,j)-;
}
}
}
cout<<ans<<endl;
}

做法②:哈希(O(N))

给每个数一个哈希值 从左往右扫一次 从右往左扫一次 如果扫到1就停下检查答案直到数组末尾或碰到下一个1  注意单个的1每次只能算一次

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> p;
const int MAXN = ;
int n, ans, T;
ll num[MAXN];
p hsh[MAXN];//每个数的哈希值
p prehsh[MAXN];//数组前缀的哈希值
p sumhsh[MAXN];//1~X数的哈希值
p update(p x, p y) { //哈希异或计算
x.first ^= y.first;
x.second ^= y.second;
return x;
}
int getans(int x) {
ll maxn = ; //从第一个1到下一个1或末端所经过的所有数最大值
ll r = x; //现在遍历到哪个数
int now = ; //目前符合条件的答案
while (r < n && num[r + ] != ) { //如果还没有到头且下一个不是1
r++; //到达下一个
maxn = max(maxn, num[r]); //维护最大值
if (r - maxn >= ) {
p xx;
xx = update(prehsh[r], prehsh[r - maxn]);
if (xx == sumhsh[maxn]) {
now++; //如果最大值不超过遍历过的数的数量且子串的哈希值与sumhsh[maxn]对应则答案++
}
}
}
return now;
}
int main() {
ll x = ;
cin >> n;
for (int i = ; i <= n; i++) {
cin >> num[i];
x ^= num[i];
}
for (int i = ; i <= n; i++) { //分配1~n对应每个值的哈希值
hsh[i].first = x ^ rand();
hsh[i].second = x ^ rand();
sumhsh[i] = hsh[i];
if (i != ) {
sumhsh[i] = update(sumhsh[i], sumhsh[i - ]); //计算数字1~i的哈希前缀
}
}
for (T = ; T <= ; T++) {
for (int i = ; i <= n; i++) {
prehsh[i] = hsh[num[i]];
if (i != ) {
prehsh[i] = update(prehsh[i], prehsh[i - ]); //计算数组前i个数的哈希前缀
}
}
for (int i = ; i <= n; i++) {
if (num[i] == ) {
if (T == ) { //单个1只能从单个方向计算一次
ans++;
}
ans += getans(i);
}
}
reverse(num + , num + + n);
}
cout << ans << endl;
return ;
}

Codeforces 1175F The Number of Subpermutations的更多相关文章

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

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

  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 55D Beautiful Number

    Codeforces 55D Beautiful Number a positive integer number is beautiful if and only if it is divisibl ...

  4. Codeforces 40 E. Number Table

    题目链接:http://codeforces.com/problemset/problem/40/E 妙啊... 因为已经确定的格子数目严格小于了$max(n,m)$,所以至少有一行或者一列是空着的, ...

  5. Codeforces 124A - The number of positions

    题目链接:http://codeforces.com/problemset/problem/124/A Petr stands in line of n people, but he doesn't ...

  6. codeforces Soldier and Number Game(dp+素数筛选)

    D. Soldier and Number Game time limit per test3 seconds memory limit per test256 megabytes inputstan ...

  7. Codeforces 55D Beautiful Number (数位统计)

    把数位dp写成记忆化搜索的形式,方法很赞,代码量少了很多. 下面为转载内容:  a positive integer number is beautiful if and only if it is  ...

  8. Codeforces 980E The Number Games 贪心 倍增表

    原文链接https://www.cnblogs.com/zhouzhendong/p/9074226.html 题目传送门 - Codeforces 980E 题意 $\rm Codeforces$ ...

  9. Codeforces 980E The Number Games - 贪心 - 树状数组

    题目传送门 传送点I 传送点II 传送点III 题目大意 给定一颗有$n$个点的树,$i$号点的权值是$2^{i}$要求删去$k$个点,使得剩下的点仍然连通,并且总权值和最大,问删去的所有点的编号. ...

随机推荐

  1. 使用canal通过mysql复制协议从binlog实现热数据nosql缓存(1)

    binlog: mysql在运行过程中执行的DML(增删改)操作都会以二进制形式记录在binlog中 canal server: canal server作为从数据库(slave)向主数据库发送dum ...

  2. 【AMAD】django-compressor -- 将JS和CSS文件压缩为一个缓存文件

    简介 个人评分 简介 django-compressor1的example: {% load compress %} {% compress css %} <link rel="sty ...

  3. OpenCV.问题&解决

    ZC:PDF:D:\_eBook\OpenCV\学习OpenCV(中文版Linuxidc.com).pdf 1.函数cvCaptureFromAVI(...) & cvCreateFileCa ...

  4. 学习笔记:CentOS7学习之二十:shell脚本的基础

    目录 学习笔记:CentOS7学习之二十:shell脚本的基础 20.1 shell 基本语法 20.1.1 什么是shell? 20.1.2 编程语言分类 20.1.3 什么是shell脚本 20. ...

  5. poj1797(dijstra变形,求最小边的最大值)

    题目链接:https://vjudge.net/problem/POJ-1797 题意:n个点,m条带权边,求点1到点n的所有路径中最小边的最大值. 思路: 和poj2253一样,只不过那题n< ...

  6. Dijstra_优先队列_前向星

    Dijstra算法求最短路径 具体实现方式 设置源点,将源点从原集u{}中取出并放入新建集s{} 找出至源点最近的点q从原集取出放入新集s{} 由q点出发,更新所有由q点能到达的仍处于原集的点到源点的 ...

  7. 封装PHP增删改查方法

    <?php class sqlModel{ public $db; public function __construct(){ try{ $dbms='mysql';//数据库类型 $dbNa ...

  8. 【死磕Java并发】—–深入分析ThreadLocal

    ThreadLoacal是什么? ThreadLocal是啥?以前面试别人时就喜欢问这个,有些伙伴喜欢把它和线程同步机制混为一谈,事实上ThreadLocal与线程同步无关.ThreadLocal虽然 ...

  9. TCP协议探究(一):报文格式与连接建立终止

    一 TCP:传输控制协议报文格式 1 TCP服务 提供面向连接.可靠的字节流服务 面向连接意味着两方通信,不支持多播和广播 可靠性的支持: 应用数据被分割成TCP认为最适合发送的数据块.由TCP传递给 ...

  10. C#通讯框架改写

    现有项目是利用C#的socket与PLC进行实时通讯,PLC有两种通讯模式——常规采集&高频采集. 其中常规采集大概在10ms左右发送一次数据,高频采集大概在2ms左右发送一次数据. 现有代码 ...