woj 1574 - K-th smallest 分治

戳这里:1574

题意:从一个长度为n的数字里去掉任意一个数字,求第k大的数字为多少。

官方题解:去掉Ri后剩下的数字,显然要么比去掉任意的Rj(j > i)的方案大,要么比去掉任意的Rj小。 所以先从后向前扫一遍预处理出去掉Ri后是比后面的都大还是都小。 然后分治之。

whu邀请赛的 A 题,当时没想出来解法,看了题解写了一下一发就 AC 了......

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 int n, k;
 4 char ans[1000010];
 5 //rank_suffix[i] 表示去掉第 i 个数字形成的新数字 在 原串的后缀 i 上去掉一个数字形成的新数字的集合中是 第 rank_suffix[i] 小的
 6 int rank_suffix[1000010];
 7
 8 int main()
 9 {
10     ans[0] = ‘0‘ - 1;
11     while(scanf("%d%d", &n, &k) != EOF) {
12         scanf("%s", ans + 1);
13         int i;
14         rank_suffix[n] = 1;
15         for(i = n - 1; i >= 1; --i) {
16             //当前数字是后缀 i 对应的集合上最大的数字
17             if(ans[i + 1] > ans[i]) {
18                 rank_suffix[i] = n - i + 1;
19             }
20             //这里可以认为当形成的数字一样大时,去掉前面的数字形成的数字更大
21             else if(ans[i + 1] == ans[i]){
22                 rank_suffix[i] = rank_suffix[i + 1] + 1;
23             }
24             //ans[i + 1] < ans[i] 时,当前数字在后缀 i 对应的集合上是最小的
25             else{
26                 rank_suffix[i] = 1;
27             }
28         }
29
30         //分治,求第 k 小
31         int res = 1;
32         for(i = 1; i <= n; ++i) {
33             if(ans[i] != ans[i - 1]) {
34                 //res 用于记录新形成的数第一次出现的位置,延时标记
35                 res = i;
36             }
37             //分治终点
38             if(rank_suffix[i] == k) {
39                 break;
40             }
41             if(rank_suffix[i] < k) {
42                 --k;
43             }
44         }
45         printf("%d\n", res);
46     }
47 }
时间: 2024-10-14 05:08:57

woj 1574 - K-th smallest 分治的相关文章

good article————K’th Smallest/Largest Element in Unsorted Array | Set 2 (Expected Linear Time)

这是本人在研究leetcode中Median of Two Sorted Arrays一题目的时候看到一篇文章,觉得非常好,其中对快速排序重新实现. 文章来源于http://www.geeksforgeeks.org/这个网站. We recommend to read following post as a prerequisite of this post. K'th Smallest/Largest Element in Unsorted Array | Set 1 Given an ar

UVALive 7148 LRIP 14年上海区域赛K题 树分治

题意 n个点组成一棵树, 带有点权. 求最长不降的路径的长度, 且路径上最大值最小值之差不超过D. 显然是树分治, 但是分治之后如何维护答案呢. 假设当前重心为g, 分别记录g出发不降路径的长度,以及最大值, 和不升路径的长度以及最小值. 这里用到一个map和二分, 线段树也可以, 但是如果用线段树还要考虑负值, 再加上线段树的clear以及稍微暴力的查询.  常数大小不好说. 1 #include <bits/stdc++.h> 2 using namespace std; 3 typede

[Algorithm] How to use Max Heap to maintain K smallest items

Let's say we are given an array: [4,1,5,2,3,0,10] We want to get K = 3 smallest items from the array and using Max heap data structure. So this is how to think about it. 1. We take first K items put it into Max Heap: 5 /     \ 4          1 2. Then we

[Swift]LeetCode786. 第 K 个最小的素数分数 | K-th Smallest Prime Fraction

A sorted list A contains 1, plus some number of primes.  Then, for every p < q in the list, we consider the fraction p/q. What is the K-th smallest fraction considered?  Return your answer as an array of ints, where answer[0] = p and answer[1] = q. E

排序之分治排序

本算法是笔者研读算法导论分治内容伪代码所写,俗话说,它山之石,可以攻玉.算导对排序有非常详细的解释,而分治排序更是其中巧妙的一种排序算法.分治排序先把数组分成[l,mid]与(mid,r]两部分,多次划分直到每个部分只有1个元素.然后把这两部分进行比较排序.(由于上一次的排序,这两个分数组内部是有序的); 举例说数组:[7,3,5,4,6,2,1],定义INF = 100,大于数组每个元素 (1).第一次划分 [7,3,5,4] , [6,2,1] (2).对[7,3,5,4]进行第二次划分 [

海量数据处理

常用的方法: Hash法.Bit-map法.Trie树.堆 TOP K 问题: 分治+Trie树/hash+小顶堆 重复问题: 位图法 排序问题: 分治法/位图法 还不是很理解

【ToReadList】六种姿势拿下连续子序列最大和问题,附伪代码(以HDU 1003 1231为例)(转载)

问题描述:       连续子序列最大和,其实就是求一个序列中连续的子序列中元素和最大的那个. 比如例如给定序列: { -2, 11, -4, 13, -5, -2 } 其最大连续子序列为{ 11, -4, 13 },最大和为20. =============================================================== 问题分析: 1.首先最朴素的方法是暴力 O(n^3) 直接两个for循环枚举子序列的首尾,然后再来个循环计算序列的和,每次更新和的最大值.

LeetCode 第二题,Median of Two Sorted Arrays

题目再现 There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). 题意解析 题目意思是给两个大小为m,n的有序数组(m,n可能为0),要求找出这两个数组的中位数.并且程序的时间复杂度必须不能超过O(log(m+n)). 这道题的

算法中的递归分析和分治法的原理

分析递归算法三种方法 替换法.迭代法.通用法(master method) 作用:分析递归算法的运行时间 分治算法 将一个问题分解为与原问题相似但规模更小的若干子问题,递归地解这些子问题,然后将这些子问题的解结合起来构成原问题的解.这种方法在每层递归上均包括三个步骤: divide(分解):将问题划分为若干个子问题 conquer(求解):递归地解这些子问题:若子问题Size足够小,则直接解决之 Combine(组合):将子问题的解组合成原问题的解 其中的第二步很关键:递归调用或直接求解  (递