zoukankan      html  css  js  c++  java
  • 「题解」洛谷 P3487 [POI2009]ARC-Architects

    题目

    P3487 [POI2009]ARC-Architects

    简化题意

    给你一个序列,让你跳出一个字典序最大的长一定的子序列。

    思路

    贪心 + 单调队列。

    每次找最大的数加入子序列,很明显这样子贪心可以保证字典序最大。

    但是记得给后面的数字留下位置。

    Code

    /*************************************************************************}
    {*                                                                       *}
    {*                     XVI Olimpiada Informatyczna                       *}
    {*                                                                       *}
    {*   Zadanie: Architekci (ARC)                                           *}
    {*   Plik:    carclib.c                                                  *}
    {*   Autor:   Bartosz Gorski                                             *}
    {*   Opis:    Biblioteka do wczytywania danych wejsciowych i wypisywania *}
    {*            wyniku                                                     *}
    {*                                                                       *}
    {*************************************************************************/
    
    #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 = 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 * 1103515245 + 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, char *com)
    {
        if(res == ERROR)
            printf("%s
    ", 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
    ", jakoscProjektu);
        if(++con_k == K)
            finish(CORRECT, "");
    }
    
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #define MAXN 15000002
    
    int k, n, a[MAXN];
    struct deque {
        int dq[MAXN], head, tail;
        void clear() {
            memset(dq, 0, sizeof dq);
            head = 1, tail = 0;
        }
        void pop_back() { --tail; }
        void pop_front() { ++head; }
        int back() { return dq[tail]; }
        int front() { return dq[head]; }
        bool empty() { return tail < head; }
        void push(int x) { dq[++tail] = x; }
    }que;
    
    int main() {
        que.clear();
        k = inicjuj();
        while (true) {
            a[++n] = wczytaj();
            if (a[n] == 0) break;
        }
        --n;
        int len = n - k + 1, last = 1;
        while(k) {
            len = n - k + 1;
            for (int i = last; i <= len; ++i) {
                while (!que.empty() && a[i] > que.back()) {
                    que.pop_back();
                }
                que.push(a[i]);
            }
            --k, last = len + 1;
            wypisz(que.front());
            que.pop_front();
        }
        return 0;
    }
    
  • 相关阅读:
    SpringMVC请求静态资源
    Spring视图和视图解析器
    @ModelAttribute运行流程
    SpringMVC模型数据处理
    SpringMVC简单映射请求参数介绍
    队列和栈的问题
    非比较排序——计数排序、基数排序、桶排序
    递归
    对数器的使用
    常见的比较排序
  • 原文地址:https://www.cnblogs.com/poi-bolg-poi/p/13590618.html
Copyright © 2011-2022 走看看