Poke here: 1574
Test instructions: Remove any number from an n-length number to find out what number of K is large.
Official solution: Removing the remaining numbers after Ri is obviously either larger than removing any RJ (J > I), or smaller than removing any RJ. So first sweep from the back to the pre-processing after removing the RI is larger or smaller than the back. Then divide and conquer it.
WHU Invitational A question, at that time did not think out solution, read the problem wrote a bit on AC ...
1#include"bits/stdc++.h"2 using namespacestd;3 intN, K;4 Charans[1000010];5 //Rank_suffix[i] means that the new number formed by removing the number i is the suffix I of the original string minus a number of the new number formed in the set is the first rank_suffix[i] small6 intrank_suffix[1000010];7 8 intMain ()9 {Tenans[0] ='0'-1; One while(SCANF ("%d%d", &n, &k)! =EOF) { Ascanf"%s", ans +1); - inti; -Rank_suffix[n] =1; the for(i = n-1; I >=1; --i) { - //The current number is the largest number on the set corresponding to the suffix i - if(Ans[i +1] >Ans[i]) { -Rank_suffix[i] = n-i +1; + } - //It can be thought that when the numbers are as large as possible, the numbers that are removed from the preceding numbers are larger. + Else if(Ans[i +1] ==Ans[i]) { ARank_suffix[i] = rank_suffix[i +1] +1; at } - //Ans[i + 1] < Ans[i], the current number is the smallest on the set corresponding to the suffix i - Else{ -Rank_suffix[i] =1; - } - } in - //divide and conquer, beg K small to intres =1; + for(i =1; I <= N; ++i) { - if(Ans[i]! = ans[i-1]) { the //Res is used to record the position of the first occurrence of the newly formed number, the time delay marker *res =i; $ }Panax Notoginseng //Divide and conquer the end - if(Rank_suffix[i] = =k) { the Break; + } A if(Rank_suffix[i] <k) { the--K; + } - } $printf"%d\n", res); $ } -}
Woj 1574-k-th Smallest divided treatment