Le rapport de la résolution des problèmes de NOIP2016Day2T2

Voir le titre original Luo Valley ( https://www.luogu.org/problem/show?pid=2827 )
En fait, cette question des caractéristiques des données écrites en détail pense personnellement que cette question même de la violence pure peut également obtenir 25 points. Ici , le segment I pour expliquer les points à cette question:
[25 min]
Nous examinons d' abord le point de données dans la plage de 1.2.3 m = 0 on trouve des données directement sortie par sujet comme manière, 4,6 points n = 1 simulation de violence aussi directe comme, faire le code spécifique mente pas ......
[65-85 minutes]
notre première pensée est de maintenir la longueur du tas tous les vers de terre, comment ça marche: chaque fois que nous avons retiré du tas le plus long ver de terre, l' a mis dans le tas après la coupe.
Se pose alors la question: chaque fois que nous faisons comment la longueur des autres vers de terre lombrics augmenter q?
Nous pouvons le faire, avec un enregistrement en cours de chaque Ajouter à des vers de terre devrait augmenter la durée du temps d'expliquer quand nous sommes arrivés à la fin de toute coupe m, puis théoriquement tous les vers de terre ont augmenté Ajouter = q * m de longueur. Mais quand nous avons besoin de découper un ver de terre, vers de terre longueur de cette augmentation est pas permis, et comment pouvons-nous l' exploiter? Nous soustrayons q enfoncé dans la pile sur elle sur la longueur des vers de terre après la coupe, nous pouvons utiliser le tas à la main et l' entrée rapide et sortie pour rendre le programme plus rapide. Lorsque vous utilisez modèle STL T priority tombera à un moment donné, je suis ici et entrée-jeu à la main et la pile de sortie pointage optimisé de 85 points, la complexité temporelle de l'algorithme est sur O ((n + m) log (n + m)) code est le suivant:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;
const int N = 1e5 + 5, M = 7e6 + 5;
int n, m, q, u, v, t, Add;
double p;

struct BigRt
{
    int g[N + M], l;

    inline void Pop()
    {
        g[1] = g[l--];
        int now = 1, nxt = 2, res = g[1];
        while (nxt <= l)
        {
            if (nxt < l && g[nxt | 1] > g[nxt]) 
            nxt |= 1;
            if (res < g[nxt])
             g[now] = g[nxt], nxt = (now = nxt) << 1;
            else break;
        }
        g[now] = res;
    }

    inline void Push(const int &res)
    {
        g[++l] = res;
        int now = l, nxt = l >> 1;
        while (nxt)
        {
            if (res > g[nxt])
             g[now] = g[nxt], nxt = (now = nxt) >> 1;
            else break;
        }
        g[now] = res;
    }
}Q;

inline int get()
{
    char ch; int res = 0; bool f = true;
    while (((ch = getchar()) < '0' || ch > '9') && ch != '-');
    if (ch == '-') f = false; 
     else res = ch - '0';
    while ((ch = getchar()) >= '0' && ch <= '9')
     res = (res << 3) + (res << 1) + ch - '0';
    return f? res : -res;
}

inline void put(int x)
{
    if (x < 0)
     x = -x, putchar('-'); 
    if (x > 9) put(x / 10);
    putchar(x % 10 + 48); 
}

inline bool cmp(const int &x, const int &y) {return x > y;}

int main()
{
    n = get(); m = get(); q = get(); 
    u = get(); v = get(); t = get();
    p = (double)u / v; Q.l = 0;
    for (int i = 1; i <= n; ++i) Q.Push(get());
    for (int i = 1; i <= m; ++i)
    {
        int x = Q.g[1] + Add; Q.Pop(); 
         if (i % t == 0) put(x), putchar(' '); 
        int l = (int)(p * x), r = x - l; 
        Q.Push(l - Add - q); Q.Push(r - Add - q);
        Add += q; 
   (i % t == 0) put(Q.g[1] + Add), putchar(' ');
        Q.Pop();    
    }
}

[100]
Maintenant , nous pouvons l' améliorer, donc nous
pensions que, si nous avions deux vers de terre vers de terre à l1, après la division ont été mis à l2, l3, alors il doit être l2 <= l1, l3 <= l1 est clairement établie alors on peut définir trois files d' attente communes représentent des vers de terre non coupée q1, q2 coupant à travers la moitié gauche, sont découpées à travers la moitié de Q3, Q1 lors de la saisie des données, l'ordre décroissant, chacune à découper lors du retrait du premier escadron de trois files d' attente après la coupe maximale , comme les segments de découpe sont pressées dans la q2 droite et à gauche, q3 de la queue et d' autres moyens ayant le même traitement de segment de mémoire, la complexité temporelle de l' algorithme est en O (n + m ), il est clair beaucoup plus rapide, avec un temps total de 1528ms

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;
typedef long long ll;
const int Maxn = 2147483647;
const int N = 1e5 + 5, M = 7e6 + 5;
int n, m, q, u, v, t, Add;
int Q[3][M], qt[3], qw[3]; 

inline int get()
{
    char ch; int res;
    while ((ch = getchar()) < '0' || ch > '9');
    res = ch - '0';
    while ((ch = getchar()) >= '0' && ch <= '9')
     res = (res << 3) + (res << 1) + ch - '0';
    return res;
}

inline void put(int x)
{ 
    if (x > 9) put(x / 10);
    putchar(x % 10 + 48); 
}

inline bool cmp(const int &x, const int &y) {return x > y;}

inline int GetMax()
{
    int res = -Maxn, k;
    for (int i = 0; i < 3; ++i)
     if (qt[i] < qw[i] && res < Q[i][qt[i] + 1])
      res = Q[i][qt[i] + 1], k = i;
    qt[k]++; return res;
}

int main()
{
    n = get(); m = get(); q = get(); 
    u = get(); v = get(); t = get();
    for (int i = 1; i <= n; ++i) Q[0][++qw[0]] = get(); 
    sort(Q[0] + 1, Q[0] + qw[0] + 1, cmp);
    for (int i = 1; i <= m; ++i)
    {
        int x = GetMax() + Add;
         if (i % t == 0) put(x), putchar(i + t > m ? '\n' : ' '); 
        int l = (ll)x * u / v, r = x - l; 
        Q[1][++qw[1]] = l - Add - q;
        Q[2][++qw[2]] = r - Add - q; Add += q; 
    }
    if (t > m) putchar('\n');
    int tmp = n + m;
    for (int i = 1; i <= tmp; ++i)
    {
        int x = GetMax() + Add;
         if (i % t == 0) {put(x); if (i + t <= tmp) putchar(' ');}
    }
    return 0;
}
Publié 41 articles originaux · louange gagné 58 · vues + 60000

Je suppose que tu aimes

Origine blog.csdn.net/a1351937368/article/details/77800431
conseillé
Classement