AC日记——Periodic RMQ Problem codeforces 803G

Posted Only U - IU

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AC日记——Periodic RMQ Problem codeforces 803G相关的知识,希望对你有一定的参考价值。

G - Periodic RMQ Problem

 

 

思路:

  题目给一段序列,然后序列复制很多次;

  维护序列很多次后的性质;

  线段树动态开点;

 

来,上代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define maxn 100005

struct TreeNodeType {
    int l, r, mid, min, flag;

    TreeNodeType *lc, *rc;

    TreeNodeType()
    {
        flag=0;
        lc = NULL;
        rc = NULL;
    }
};
struct TreeNodeType *root, *rot;

int n, k, m;

inline void in(int &now)
{
    char Cget = getchar(); now = 0;
    while (Cget > 9 || Cget < 0) Cget = getchar();
    while (Cget >= 0&&Cget <= 9)
    {
        now = now * 10 + Cget - 0;
        Cget = getchar();
    }
}

void tree_build_ori(TreeNodeType *&now, int l, int r)
{
    if (now == NULL)
    {
        now = new TreeNodeType;
        now->l = l, now->r = r;
        now->mid = (l + r) >> 1;
    }
    if (l == r)
    {
        in(now->min);
        return;
    }
    tree_build_ori(now->lc, l, now->mid);
    tree_build_ori(now->rc, now->mid + 1, r);
    now->min = min(now->lc->min, now->rc->min);
}

int tree_query_ori(TreeNodeType *&now, int l, int r)
{
    if (now->l == l&&now->r == r) return now->min;
    if (l > now->mid) return tree_query_ori(now->rc, l, r);
    else if (r <= now->mid) return tree_query_ori(now->lc, l, r);
    else return min(tree_query_ori(now->lc, l, now->mid), tree_query_ori(now->rc, now->mid + 1, r));
}

inline void tree_down(TreeNodeType *&now)
{
    now->lc->min = now->flag;
    now->lc->flag = now->flag;
    now->rc->min = now->flag;
    now->rc->flag = now->flag;
    now->flag = 0;
}

int solve(int l, int r)
{
    if(r-l+1>=n) return rot->min;
    l%=n,r%=n;
    if(l==0) l=n;
    if(r==0) r=n;
    if(r<l) return min(tree_query_ori(rot, l, n), tree_query_ori(rot, 1, r));
    else return tree_query_ori(rot,l,r);
}

void tree_change(TreeNodeType *&now, int l, int r, int x)
{
    if (now->l == l&&now->r == r)
    {
        now->min = x;
        now->flag = x;
        return;
    }
    if (now->rc == NULL)
    {
        now->rc = new TreeNodeType;
        now->rc->l = now->mid + 1;
        now->rc->r = now->r;
        now->rc->mid = (now->rc->r + now->rc->l) >> 1;
        now->rc->min = solve(now->rc->l, now->rc->r);
    }
    if (now->lc == NULL)
    {
        now->lc = new TreeNodeType;
        now->lc->l = now->l;
        now->lc->r = now->mid;
        now->lc->mid = (now->lc->l + now->lc->r) >> 1;
        now->lc->min = solve(now->lc->l, now->lc->r);
    }
    if (now->flag) tree_down(now);
    if (l > now->mid) tree_change(now->rc, l, r, x);
    else if (r <= now->mid) tree_change(now->lc, l, r, x);
    else
    {
        tree_change(now->lc, l, now->mid, x);
        tree_change(now->rc, now->mid + 1, r, x);
    }
    now->min = min(now->lc->min, now->rc->min);
}

int tree_query(TreeNodeType *&now, int l, int r)
{
    if (now->l == l&&now->r == r) return now->min;
    if (now->rc == NULL)
    {
        now->rc = new TreeNodeType;
        now->rc->l = now->mid + 1;
        now->rc->r = now->r;
        now->rc->mid = (now->rc->r + now->rc->l) >> 1;
        now->rc->min = solve(now->rc->l, now->rc->r);
    }
    if (now->lc == NULL)
    {
        now->lc = new TreeNodeType;
        now->lc->l = now->l;
        now->lc->r = now->mid;
        now->lc->mid = (now->lc->l + now->lc->r) >> 1;
        now->lc->min = solve(now->lc->l, now->lc->r);
    }
    if (now->flag) tree_down(now);
    if (l > now->mid) return tree_query(now->rc, l, r);
    else if (r <= now->mid) return tree_query(now->lc, l, r);
    else return min(tree_query(now->lc, l, now->mid), tree_query(now->rc, now->mid + 1, r));
    now->min = min(now->lc->min, now->rc->min);
}

int main()
{
    root = NULL, rot = NULL; int op, l, r, x;
    in(n), in(k), tree_build_ori(rot, 1, n), in(m);
    root = new TreeNodeType;
    root->l = 1, root->r = n*k, root->mid = 1 + n*k >> 1, root->min = rot->min;
    for (; m--;)
    {
        in(op), in(l), in(r);
        if (op == 2) printf("%d\n", tree_query(root, l, r));
        else in(x),tree_change(root, l, r, x);
    }
    return 0;
}

 

以上是关于AC日记——Periodic RMQ Problem codeforces 803G的主要内容,如果未能解决你的问题,请参考以下文章

#RMQ,动态开点线段树#CF803G Periodic RMQ Problem

(WAWAWAWAWAWAW) G. Periodic RMQ Problem

Codeforces 803G Periodic RMQ Problem ST表+动态开节点线段树

Repeats SPOJ - REPEATS (AC自动机 + RMQ)

AC日记——Dividing poj 1014

AC日记——Oulipo poj 3461