luogu P3567 [POI2014]KUR-Couriers

二次联通门 : luogu P3567 [POI2014]KUR-Couriers

MMP

指针 RE + MLE + WA.....

不得已...向黑恶的数组实力低头

/*
    指针
     

*/
#include <algorithm>
#include <cstdio>

#define Max 2000009

void read (int &now)
{
    now = 0;
    register char word = getchar ();
    while (word < '0' || word > '9')
        word = getchar ();
    while (word >= '0' && word <= '9')
    {
        now = now * 10 + word - '0';
        word = getchar ();
    }
}

inline int min (int a, int b)
{
    return a < b ? a : b;
}

inline int max (int a, int b)
{
    return a > b ? a : b;
}

struct Segment_Tree_Data 
{
    Segment_Tree_Data *Left, *Right;
    
    int key;
    
    Segment_Tree_Data ()
    {
        key = 0;
        Left = Right = NULL;
    }
};

Segment_Tree_Data *Root[Max];

int N, M;

class Lasting_Segment_Tree_Type
{
    private :
        
        int Query (Segment_Tree_Data *&Last, Segment_Tree_Data *&now, int l, int r)
        {
            if (l == r)
                return l;
            register int Mid = l + r >> 1;
            if (now->Left->key - Last->Left->key > Need)
                return Query (Last->Left, now->Left, l, Mid);
            else if (now->Left->key - Last->Right->key > Need)
                return Query (Last->Right, now->Right, Mid + 1, r);
            return 0;
        }
        
        int Need;
        
    public :
        
        
        void Build (Segment_Tree_Data *&now, int l, int r)
        {
            now = new Segment_Tree_Data;
            if (l == r)
                return ;
            register int Mid = l + r >> 1;
            Build (now->Left, l, Mid);
            Build (now->Right, Mid + 1, r);
        }
        
        void Updata (Segment_Tree_Data *Last, Segment_Tree_Data *&now, int pos, int l, int r)
        {
            now = new Segment_Tree_Data;
            now->key = Last->key + 1;
            if (l == r)
                return ;
            register int Mid = l + r >> 1;
            if (pos <= Mid)
            {
                now->Right = Last->Right;
                Updata (Last->Left, now->Left, pos, l, Mid);
            }
            else
            {
                now->Left = Last->Left;
                Updata (Last->Right, now->Right, pos, Mid + 1, r);
            }
        }
        
        
        int Query_Section (int l, int r)
        {
            Need = r - l + 1 >> 1;
            return Query (Root[l - 1], Root[r], 1, N);
        }
};

Lasting_Segment_Tree_Type Tree;


int rank[Max];
int number[Max];

int main (int argc, char *argv[])
{
    read (N);
    read (M);
    Tree.Build (Root[0], 1, N);
    for (int i = 1; i <= N; i++)
    {
        read (number[i]);
        Root[i] = Root[i - 1];
        Tree.Updata (Root[i - 1], Root[i], number[i], 1, N); 
    }
    for (int x, y; M--; )
    {
        read (x);
        read (y);
        printf ("%d
", Tree.Query_Section (x, y));
    }
    return 0;
}

数组...

/*
    luogu P3567 [POI2014]KUR-Couriers
    
    主席树 + 权值线段树 + 离散化
    
    每次查询的时候向大于r-l+1 / 2的一边走
    
    若查不到则返回0     

*/
#include <algorithm>
#include <cstdio>

#define Max 800006

void read (int &now)
{
    now = 0;
    register char word = getchar ();
    while (word < '0' || word > '9')
        word = getchar ();
    while (word >= '0' && word <= '9')
    {
        now = now * 10 + word - '0';
        word = getchar ();
    }
}

struct Segment_Tree_Date
{
    int Left, Right;
    int key;
    
};

int Root[Max];

Segment_Tree_Date tree[Max << 3];


class Lasting_Segment_Tree_Type
{
    
    private :
        
        int Tree_Count;

    public :
        
        void Build (int &now, int l, int r)
        {
            now = ++Tree_Count;
            if (l == r)
                return ;
            register int Mid = l + r >> 1;
            Build (tree[now].Left, l, Mid);
            Build (tree[now].Right, Mid + 1, r);
        }
        
        void Updata (int Last, int &now, int l, int r, int pos)
        {
            now = ++Tree_Count;
            tree[now].key = tree[Last].key + 1;
            if (l == r)
                return ;
            int Mid = l + r >> 1;
            if (pos <= Mid)
            {
                tree[now].Right = tree[Last].Right;
                Updata (tree[Last].Left, tree[now].Left, l, Mid, pos);
            }
            else 
            {
                tree[now].Left = tree[Last].Left;
                Updata (tree[Last].Right, tree[now].Right, Mid + 1, r, pos);
            }
        }
        
        int Query (int Last, int now, int l, int r, int Need)
        {
            if (l == r)
                return l;
            register int Mid = l + r >> 1;
            if (tree[tree[now].Left].key - tree[tree[Last].Left].key > Need)
                return Query (tree[Last].Left, tree[now].Left, l, Mid, Need);
            else if (tree[tree[now].Right].key - tree[tree[Last].Right].key > Need)
                return Query (tree[Last].Right, tree[now].Right, Mid + 1, r, Need);
            return 0;
        }
};

int N, M;

int number[Max];
int rank[Max];

Lasting_Segment_Tree_Type Tree;

int main (int argc, char *argv[])
{
    read (N);
    read (M);
    for (int i = 1; i <= N; i++)
    {
        read (number[i]);
        rank[i] = number[i];
    }
    std :: sort (rank + 1, rank + 1 + N);
    int Size = std :: unique (rank + 1, rank + 1 + N) - rank - 1;
    Tree.Build (Root[0], 1, Size); 
    for (int i = 1; i <= N; i++)
    {
        number[i] = std :: lower_bound (rank + 1, rank + 1 + Size, number[i]) - rank;
        Tree.Updata (Root[i - 1], Root[i], 1, Size, number[i]); 
    }
    for (int x, y; M--; )
    {
        read (x);
        read (y);
        printf ("%d
", rank[Tree.Query (Root[x - 1], Root[y], 1, Size, y - x + 1 >> 1)]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ZlycerQan/p/6940725.html