bzoj1136: [POI2009]Arc

时间:2023-03-09 20:18:51
bzoj1136: [POI2009]Arc

Description

给定一个序列{ai | 1 <= ai <= 1000000000 且 1 <= i <= n 且 n <= 15000000}和一个整数 k (k <= n 且 k <= 1000000),求出a的一个长度为k的子序列{a[bi]}满足: (1) 1 <= b1 <= b2 <= ... <= bk (2) 在满足(1)的情况下 {a[b1], a[b2], ... , a[bk]} 字典序最大。

Input

第一行一个数k,以下一行,为序列ai。以一个单独的0结束

Output

k行,每行一个数,其中第i行为a[bi]。

Sample Input

12
5 8 3 15 8 0

Sample Output

12
15
8

题解:

http://blog.****.net/popoqqq/article/details/44812723

code:

 #include <stdlib.h>
#include <stdio.h>
#include <time.h> #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 = ; // 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 = ; static inline int rand2(int a, int b){
rand2_status = rand2_status * + ;
int x = rand2_status;
if (x < ) x = -x; // -2^31 sie nie zdarza :D
x >>= ;
x = a + x % (b - a + );
return x;
} /* test losowy */
static inline int random_test()
{
return rand2(, A);
} /* test z dlugim podciagiem nierosnacym */
static inline int decreasing_test()
{
int tmp;
if(bre == ) {
bre = rand2(, (N - lib_n + - len_sub));
tmp = A;
A -= rand2(, (A - ) / len_sub);
len_sub--;
}
else {
bre--;
tmp = rand2(, A);
}
return tmp;
} /* test z dlugim podciagiem niemalejacym */
static inline int increasing_test()
{
return bou - decreasing_test();
} static void finish(int res, char *com)
{
if(res == ERROR)
printf("%s\n", com);
exit();
} /* Inicjuje dane wejsciowe i zwraca liczbe projektow */
int inicjuj()
{
if(init == )
finish(ERROR, "Program zawodnika moze wywolac funkcje inicjuj tylko raz!!!");
init = ;
scanf("%d", &K);
if (K > ){
TYP = ;
N = MAX_N + ;
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 < || 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 = ;
lib_n = ;
is_end = ;
if(TYP == || TYP == ) {
len_sub = PAR;
bre = ;
}
if(TYP == )
bou = A--;
return K;
} /* Sluzy do wczytania ciagu reprezentujacego jakosci projektow */
int wczytaj()
{
if(unlikely(init == ))
finish(ERROR, "Program zawodnika nie wywolal funkcji inicjuj!!!");
if(unlikely(lib_n > N || is_end == ))
finish(ERROR, "Program zawodnika wywolal funkcje wczytaj po otrzymaniu informacji o koncu ciagu!!!");
if(unlikely(lib_n == N))
return ;
lib_n++;
switch (TYP) {
case :
scanf("%d", &A);
if(A == )
is_end = ;
return A;
break;
case : return random_test(); break;
case : return increasing_test(); break;
case : return decreasing_test(); break;
default:
finish(ERROR, "Nieznany typ testu");
}
return -;
} /* Sluzy do wypisania wyznaczonego podciagu */
void wypisz(int jakoscProjektu)
{
if(init == )
finish(ERROR, "Program zawodnika nie wywolal funkcji inicjuj!!!");
printf("%d\n", jakoscProjektu);
if(++con_k == K)
finish(CORRECT, "");
}
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
char ch;
bool ok;
void read(int &x){
for (ok=,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=;
for (x=;isdigit(ch);x=x*+ch-'',ch=getchar());
if (ok) x=-x;
}
const int maxk=;
int k,n,x,a[maxk];
struct Data{
int head,tail,val[maxk];
void init(){head=,tail=;}
void push(int v){
while (head<=tail&&val[tail%maxk]<v) tail--;
if (tail-head+<k) val[(++tail)%maxk]=v;
}
void pop(){head++;}
int front(){return val[head%maxk];}
}que;
int main(){
que.init(),k=inicjuj();
for (n=;n<k;n++) a[n]=wczytaj(); n--;
while (x=wczytaj(),x){
a[(++n)%maxk]=x;
que.push(a[(n-k)%maxk]);
}
for (int i=k-;i>=;i--) que.push(a[(n-i)%maxk]),wypisz(que.front()),que.pop();
return ;
}