P3487 [POI 2009] ARC-Architects

题目描述

给定一个序列 $a_i$($1\leq a_i\leq 10^9$)且 $1\leq i\le n$ 且 $n\leq 1.5\times 10^7$,和一个整数 $k$($k\leq n$ 且 $k\leq 10^6$),求出 $a$ 的一个长度为 $k$ 的子序列 $a_{b_i}$ 满足: 1. $1\leq b_1\leq b_2\leq \ldots\leq b_k$ 2. 在满足 $1$ 的情况下 $a_{b_1}, a_{b_2},\ldots , a_{b_k}$ 字典序最大。

输入格式

输出格式

说明/提示

本题原为交互题,为评测方便,需要将下面的代码粘贴到文件中。 将第一次输入改为 `=inicjuj()` 形式,将之后的每一次输入改为 `=wczytaj()` 形式,将输出改为 `wypisz(jakoscProjektu)` 形式(`jakoscProjektu` 代表你输出的数)。 ```cpp #include #include #include #define MAGIC_BEGIN -435634223 #define MAGIC_END -324556462 #define MIN_K 1 #define MAX_K 1000000 #define MAX_N 15000000 #define MIN_A 1 #define MAX_A 1000000000 #define MIN_TYP 1 #define MAX_TYP 3 #define MIN_PAR 0 #define MAX_PAR 1000000000 #define ERROR 0 #define CORRECT 1 #define unlikely(x) __builtin_expect(!!(x), 0) static int init = 0; // czy zostala juz wywolana funkcja inicjuj() static int lib_n; // ile biblioteka podala juz liczb static int con_k; // ile zawodnik podal liczb static int N, K, A, TYP, PAR; // parametry testu wczytywane z pliku static int bre, len_sub, bou, is_end; // zmienne pomocnicze static int rand2_status = 198402041; static inline int rand2(int a, int b){ rand2_status = rand2_status * 1103515245ll + 12345; int x = rand2_status; if (x < 0) x = -x; // -2^31 sie nie zdarza :D x >>= 1; x = a + x % (b - a + 1); return x; } /* test losowy */ static inline int random_test() { return rand2(1, A); } /* test z dlugim podciagiem nierosnacym */ static inline int decreasing_test() { int tmp; if(bre == 0) { bre = rand2(0, (N - lib_n + 1 - len_sub)); tmp = A; A -= rand2(0, (A - 1) / len_sub); len_sub--; } else { bre--; tmp = rand2(1, A); } return tmp; } /* test z dlugim podciagiem niemalejacym */ static inline int increasing_test() { return bou - decreasing_test(); } static void finish(int res, const char com[]) { if(res == ERROR) printf("%s\n", com); exit(0); } /* Inicjuje dane wejsciowe i zwraca liczbe projektow */ int inicjuj() { if(init == 1) finish(ERROR, "Program zawodnika moze wywolac funkcje inicjuj tylko raz!!!"); init = 1; scanf("%d", &K); if (K > 0){ TYP = 0; N = MAX_N + 2; return K; } int magic_begin, magic_end; scanf("%d%d", &magic_begin, &TYP); if(magic_begin != MAGIC_BEGIN || TYP < MIN_TYP || TYP > MAX_TYP) finish(ERROR, "Program zawodnika nie moze korzystac z stdin!!!"); scanf("%d%d%d%d", &N, &K, &A, &PAR); if(N < 1 || N > MAX_N || N < K || K > MAX_K || A < MIN_A || A > MAX_A || PAR < MIN_PAR || PAR > MAX_PAR) finish(ERROR, "Program zawodnika nie moze korzystac z stdin!!!"); scanf("%d", &magic_end); if(magic_end != MAGIC_END) finish(ERROR, "Program zawodnika nie moze korzystac z stdin!!!"); con_k = 0; lib_n = 0; is_end = 0; if(TYP == 2 || TYP == 3) { len_sub = PAR; bre = 0; } if(TYP == 2) bou = A--; return K; } /* Sluzy do wczytania ciagu reprezentujacego jakosci projektow */ int wczytaj() { if(unlikely(init == 0)) finish(ERROR, "Program zawodnika nie wywolal funkcji inicjuj!!!"); if(unlikely(lib_n > N || is_end == 1)) finish(ERROR, "Program zawodnika wywolal funkcje wczytaj po otrzymaniu informacji o koncu ciagu!!!"); if(unlikely(lib_n == N)) return 0; lib_n++; switch (TYP) { case 0: scanf("%d", &A); if(A == 0) is_end = 1; return A; break; case 1: return random_test(); break; case 2: return increasing_test(); break; case 3: return decreasing_test(); break; default: finish(ERROR, "Nieznany typ testu"); } return -1; } /* Sluzy do wypisania wyznaczonego podciagu */ void wypisz(int jakoscProjektu) { if(init == 0) finish(ERROR, "Program zawodnika nie wywolal funkcji inicjuj!!!"); printf("%d\n", jakoscProjektu); if(++con_k == K) finish(CORRECT, ""); } ```