AtCoderGC038B - Sorting a Segment 数据结构 + RMQ

题意:给定一个长度为N的排列,你只能对其中长度为K的连续子序列进行一次从小到大的排序,问:排序之后能形成多少不同的排列?

数据范围: 1 <= n, k <= 200,000, k <= n.

-----------------------------------分割线--------------------------------

分析此题,我们发现,长度为K的连续子序列在原排列中只有 N-K+1个,也就是说只会有N-K+1个排序情况,得出答案的上界N-K+1.

考虑上界中有多少连续子序列重复计数M,减去M即为答案。

那么剩下的问题就是统计每一个排序之后的连续子序列相同的个数M了。

朴素做法:枚举每一个长度为K的区间,对区间内从小到大排一下序,得出原排列,与其他排列进行比较,统计相同排列的个数cnt,累加每个cnt-1即可。

时间复杂度  O(N^2*Klog(K)).

思考一下优化方法。

设原排列为A1,A2,A3,........,An。

假设一个区间[l,r]排序之后为原排列为P(l,r).

那么如果P(l1,r1) = P(l2,r2)且 r1 - l1 +1 = r2 - l2 + 1 = K。

当且仅当存在以下两种情况,上式成立:

(1) 区间[l1,r1] 和 区间[l2,r2] 原本就从小到大有序。

(2) 区间[l1,r1] 和 区间[l2,r2]相邻,即 l2 = l1+1,r2 = r1+1,且 min[l1,r2] = a[l1],max[l1,r2] = a[r2]. 

结论(1)的正确性显然。

主要讨论结论(2)的正确性:

我们可以知道,区间[l1,r1] 和 区间[l2, r2] 的区间交为[l2,r1],区间并为[l1,r2]。

如果只考虑区间[l2,r1],那么排序结果显然相同。

而P(l1,r1) <=> P(l2,r1)U 由区间[l1,l2-1]中所有元素基于大小关系插入区间[l2,r1]的相应位置。

区间[l2,r2] 同理。

于是我们只需解决区间[l1,l2-1] 和区间 [r1+1,r2]对区间[l2,r1]的 排序影响。

如果[l1,r1] 与 [l2,r2] 不相邻,且非情况(1),则 P(l1,r1) != P(l2,r1),P(l2,r2)!= P(l2,r1),P(l1,r1)!= P(l2,r1)!= P(l2,r2),不存在。

则当l2 = l1+1 时,若min[l1,r2] = a[l1],则P(l1,r1)= P(l2,r1),若max[l1,r2] = a[r2],则P(l2,r2)= P(l2,r1).由传递性可知:P(l1,r1)= P(l2,r1)= P(l2,r2)。结论成立。

证毕。

于是根据这两个结论,我们可以首先求出情况(1)的重复数,扫一遍原排列,求出长度大于等于K的升序区间数量。

对于情况(2),我们先选取区间[1,K],维护最大值和最小值,接着左端点和右端点指针分别往右移,转移到区间[2,K+1],对于区间[1,K]和[2,K+1],判断是否符合min[1,K+1] = a[1] 并且 max[1,K+1] = a[K+1].若符合,则累加到M中,否则继续往右移,直到右端点到N为止。

维护动态区间最大值和最小值可以用STL的堆 或者 set 维护。

插入删除复杂度O(logN),遍历时间复杂度O(N),总时间复杂度O(NlogN).可以通过。

其实还可以用单调队列维护,总时间复杂度降为O(N),大家有兴趣可以尝试一下(我就不试了QAQ).

堆的代码如下:

#include<bits/stdc++.h>#define ll long long
#define mp make_pair
#define rep(i, a, b) for(int i = (a);i <= (b);i++)
#define per(i, a, b) for(int i = (a);i >= (b);i--)using namespace std;typedef pair<int, int> pii;
typedef double db;
const int N = 1e6 + 50;
int n, k, a[N], cnt = 0, flag = 0; 
int ans = 0, maxx, minn, pmax, pmin;
int vis[N], f[N];
priority_queue < int, vector<int>, greater<int> > q;
priority_queue < int, vector<int>, less<int> > p;
inline int read(){int x = 0, f = 1;char ch = getchar();while(ch < '0' || ch > '9'){if(ch == '-') f = -1; ch = getchar();}while(ch >='0' && ch <='9'){x = (x<<3)+(x<<1)+(ch^48); ch = getchar();}return x*f;
}
void init(){n = read(); k = read(); rep(i, 1, n) a[i] = read();rep(i, 1, k) p.push(a[i]), q.push(a[i]);rep(i, 2, n){if(a[i] > a[i-1]){int sum = 0;while(a[i] > a[i-1] && i <= n) i++, sum++;if(sum >= k-1) cnt ++;}}ans = n-k+1;int l = 1, r = k;while(r <= n){r++;if(r > n) break;while(vis[q.top()]) q.pop(); while(f[p.top()]) p.pop();if(a[l] == q.top() && a[r] > p.top()){q.pop(); p.push(a[r]);q.push(a[r]);f[a[l]] = 1;ans --;}else if(a[l] == q.top() && a[r] < p.top()){q.pop(); p.push(a[r]);q.push(a[r]);f[a[l]] = 1;}else if(a[l] == p.top()){p.pop(); p.push(a[r]);q.push(a[r]);vis[a[l]] = 1;}else if(a[l] != q.top() && a[l] != p.top()){p.push(a[r]); q.push(a[r]);f[a[l]] = 1, vis[a[l]] = 1;}l++;}if(!cnt) printf("%d\n", ans);else printf("%d\n", ans - cnt+1);
}
int main(){init();return 0;
}
View Code

STL的<set>代码如下:

#include<bits/stdc++.h>#define ll long long
#define mp make_pair
#define rep(i, a, b) for(int i = (a);i <= (b);i++)
#define per(i, a, b) for(int i = (a);i >= (b);i--)using namespace std;typedef pair<int, int> pii;
typedef double db;
const int N = 1e6 + 50;
int n, k, a[N], ans = 0,  cnt;
set <int> s;
set <int>::iterator it;
inline int read(){int x = 0, f = 1;char ch = getchar();while(ch < '0' || ch > '9'){if(ch == '-') f = -1; ch = getchar();}while(ch >='0' && ch <='9'){x = (x<<3)+(x<<1)+(ch^48); ch = getchar();}return x*f;
}
void init(){n = read(); k = read();rep(i, 1, n) a[i] = read();rep(i, 1, k) s.insert(a[i]);rep(i, 2, n){if(a[i] > a[i-1]){int sum = 0;while(a[i] > a[i-1] && i <= n) i++, sum++;if(sum >= k-1) cnt ++;}}ans = n-k+1;int l = 1, r = k;while(l <= r && r <= n){r++;if(r > n) break;s.insert(a[r]);if(*(s.rbegin()) == a[r] && (*s.begin()) == a[l]) ans --;s.erase(a[l]); l++;}if(!cnt) printf("%d\n", ans);else printf("%d\n", ans - cnt+1);
}
int main(){init();return 0;
}
View Code

 备注:本题堆的速度比<set>要快,但是代码实现难度更大,推荐用<set>.

转载于:https://www.cnblogs.com/smilke/p/11567189.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/549488.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

添加栏目HyperLink

HyperLink控件&#xff1a;NavigateUrl属性指定跳转页面。页面绑定函数&#xff1a;private void BindPage(){string action Request.QueryString["action"].ToString();if (action "add"){Button1.Text "添加";Label1.Text "添加"…

luogu P2216 [HAOI2007]理想的正方形 递推+ST表

题意&#xff1a;有一个a*b的整数组成的矩阵&#xff0c;现请你从中找出一个n*n的正方形区域&#xff0c;使得该区域所有数中的最大值和最小值的差最小。 数据规模&#xff1a; &#xff08;1&#xff09;矩阵中的所有数都不超过1,000,000,000 &#xff08;2&#xff09;20%的数…

网络管理员必看

值得一看的东西转载于:https://blog.51cto.com/740542/147758

[USACO12MAR]花盆Flowerpot 二分答案+单调队列

题意&#xff1a; 给出N滴水的坐标&#xff0c;y表示水滴的高度&#xff0c;x表示它下落到x轴的位置。 每滴水以每秒1个单位长度的速度下落。你需要把花盆放在x轴上的某个位置&#xff0c;使得从被花盆接着的第1滴水开始&#xff0c;到被花盆接着的最后1滴水结束&#xff0c;之…

jQuery使用手册

jQuery是一款同prototype一样优秀js开发库类&#xff0c;特别是对css和XPath的支持&#xff0c;使我们写js变得更加方便&#xff01;如果你不是个js高手又想写出优 秀的js效果&#xff0c;jQuery可以帮你达到目的&#xff01;下载地址&#xff1a;Starterkit &#xff08;http:…

线程池三种队列使用,SynchronousQueue,LinkedBlockingQueue,ArrayBlockingQueue

使用方法&#xff1a; private static ExecutorService cachedThreadPool new ThreadPoolExecutor(4, Runtime.getRuntime().availableProcessors() * 2, 0, TimeUnit.MILLISECONDS, new SynchronousQueue<>(), r -> new Thread(r, "ThreadTest"));1.Synch…

全志_外部中断

全志_外部中断 平台&#xff1a;全志A64 源码&#xff1a;Android 7.1  Linux3.1 1 #include <linux/init.h>2 #include <linux/module.h>3 #include <linux/fs.h>4 #include <linux/device.h>5 #include <linux/slab.h>6 #include <linux/…

又要开始工作了

“出来混&#xff0c;迟早要还的&#xff01;”&#xff0c;用在工作与休息上也是一样&#xff0c;累积下来的事情真让人身心疲惫&#xff0c;幸好过去的这几天精神还不错&#xff0c;竟然好像要治好我赖床的毛病了。看起来&#xff0c;精神上的压力会比身体上的压力对人的摧残…

[ZJOI2007]时态同步 树形DP

题意&#xff1a;给定一棵N个节点的无根树&#xff0c;每条边都有一个权值V&#xff0c;选取其中一个点作为关键点&#xff0c;你可以任意增加某条边的权值&#xff0c;求使得从关键点出发&#xff0c;到任意一个叶子节点的距离都相同所需要增加的权值和。 数据范围&#xff1a…

apache ,php,mysql的安装

apache.org 下载安装apache php.net 下载php&#xff0c;解压缩&#xff08;注意拷贝dll到windows/system32&#xff0c;并且拷贝php.ini到windows文件夹&#xff0c;修改extention-dir&#xff0c;和对mysql的支持&#xff09; mysql.com 下载安装mysql 安装顺序也是apache&am…

题解P3942_将军令

初始数组忘了赋初值&#xff0c;&#xff0c;&#xff0c;我真是个机灵鬼 还有这题是三倍经验P2279&&P2016&#xff0c;这题的实现思想来自P2279首个题解 luogu 简化题意 给你一棵树&#xff0c;你有一些可以覆盖范围为$k$的障碍物&#xff0c;问最少放几个障碍物可以使…

Hitv8 文件批量重命名工具

本工具用于单文件或批量文件文件名、文件类型扩展名重命名的小工具&#xff0c;欢迎使用&#xff01;使用说明&#xff1a; 1、使用拖放方式&#xff0c;将文件拖入列表框即可 2、可以不输文件名&#xff0c;表示文件名不变&#xff0c;只改类型&#xff1b; 类型也可以自已输入…

[SCOI2009]生日礼物 单调性尺取法

题意&#xff1a;给你n个k种颜色的点&#xff0c;每个点都有坐标和颜色两个属性&#xff0c;选出一个长度尽量短的区间&#xff0c;使得每种颜色的点都在区间内出现。 数据范围&#xff1a; 对于50%的数据&#xff0c; N≤10000&#xff1b; 对于80%的数据&#xff0c; N≤8000…

就算忘了自己也忘不了你

就算忘了自己也忘不了你——代腾飞 2009年4月24日 于成都曾经你说要我紧紧地抱住你让我们的两颗心能紧贴在一起用你的柔情将他们水浮交融彼此渗透到对方的心底我毫不犹豫照做 曾经你说你要用你的脚轻轻放在我的胸膛上你好走到离我心最近的地方让你的脚印镌刻在我的心里成为不…

PJ2018T4 对称二叉树 树形结构

题意&#xff1a;现在给出一棵二叉树&#xff0c;希望你找出它的一棵子树&#xff0c;该子树为对称二叉树&#xff0c;且节点数最多。请输出这棵子树的节点数。对称二叉树满足&#xff1a;将这棵树所有节点的左右子树交换后&#xff0c;新树和原树对应位置的结构相同且点权相等…

Flex的事件(十四)

一、 关于键盘事件<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />程序响应一个按键或一系列按键并执行一些动作&#xff0c;例如Controlq退出程序。Flex支持所有来自后台操作系统的所有组合键操作&#xff0c;它同样允许你覆…

EditPlus构建轻量级编译环境

你还在为机子跑VS&#xff0c;VC6.0吃力而苦恼吗&#xff1f;最近发现网上一个小窍门&#xff0c;就是用EditPlus文本编辑器构建轻量级编译环境&#xff0c; 轻量级的东西就是受人喜欢&#xff0c;要不说Spring能流行起来呢。最近自学C#&#xff0c;有了Java思想&#xff0c;加…

OCP-052考试题库汇总(58)-CUUG内部解答版

In one of your databases: 1.USER1 and USER2 have no system privileges. 2.ROLE1 only has these privileges: ?CREATE SESSION ?CREATE TABLE ?CREATE VIEW Examine these commands: SQL> conn / as sysdba Connected. SQL> GRANT create table, role1 TO user1 W…

提高ASP.Net应用程序性能的十大方法

一、返回多个数据集 检查你的访问数据库的代码&#xff0c;看是否存在着要返回多次的请求。每次往返降低了你的应用程序的每秒能够响应请求的次数。通过在单个数据库请求中返回多个结果集&#xff0c;可以减少与数据库通信的时间&#xff0c;使你的系统具有扩展性&#xff0c;…

【NOIP2015提高组】子串 区间DP+滚动数组优化

题意&#xff1a; 有两个仅包含小写英文字母的字符串 A 和 B。 现在要从字符串 A 中取出 k 个互不重叠的非空子串&#xff0c;然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一个新的字符串。 请问有多少种方案可以使得这个新串与字符串 B 相等&#xff1f; …