(WAWAWAWAWAWAW) G. Periodic RMQ Problem

没有联通门 : Codeforces G. Periodic RMQ Problem

/*

    Codeforces G. Periodic RMQ Problem

    MMP
    什么动态开点线段树啊 

    。。。
    YY了个非常可行的做法
    码完后交一下发现RE了几个点。。

    就思考哪里有问题

    突然之间, 老泪纵横。。

    MMP  我写了这是个什么玩意啊

    仔细想想我TM不就是写了个全空间的主席树吗。。。。脑子有病啊。。
    静言思之, 躬自悼矣。。反是不思,亦已焉哉

    不写啦!
*/
#include <cmath>
#include <cstdio>

#define Max 100008
#define INF 1e8

void read (int &now)
{
    now = 0;
    register char word = getchar ();
    bool temp = false;
    while (word < ‘0‘ || word > ‘9‘)
    {
        if (word == ‘-‘)
            temp = true;
        word = getchar ();
    }
    while (word >= ‘0‘ && word <= ‘9‘)
    {
        now = now * 10 + word - ‘0‘;
        word = getchar ();
    }
    if (temp)
        now = -now;
}

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

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

int N, K;

int number[Max];

struct Segment_Tree_Date
{
    Segment_Tree_Date *Left, *Right;

    int l, r;

    int Mid;
    int key;
    int Flandre;
    Segment_Tree_Date ()
    {
        Left = NULL;
        Right = NULL;
        key = 0;
        Flandre = 0;
    }
};

Segment_Tree_Date *Root;

int Size;

class Segment_Tree_Type
{
    public :

        void Build (Segment_Tree_Date *&now, int l, int r, int k)
        {
            if (l == r)
            {
                now->key = number[l - (k - 1) * N];
                return;
            }
            now->Mid = l + r >> 1;
            Build (now->Left, l, now->Mid, k);
            Build (now->Right, now->Mid + 1, r, k);
            now->key = min (now->Left->key, now->Right->key);
        }

        void Whole_Updata (Segment_Tree_Date *&now, int l, int r)
        {
            if (now->l == now->r)
                return ;
            if (now->Flandre)
            {
                now->Left->key = now->Flandre;
                now->Right->key = now->Flandre;

                now->Left->Flandre = now->Flandre;
                now->Right->Flandre = now->Flandre;

                now->Flandre = 0;
            }
            Whole_Updata (now->Left, l, now->Mid);
            Whole_Updata (now->Right, now->Mid + 1, r);
            now->key = min (now->Left->key, now->Right->key);
        }

        int Query (Segment_Tree_Date *&now, int l, int r)
        {
            if (l <= now->l && now->r <= r)
                return now->key;
            if (now->Flandre)
            {
                now->Left->key = now->Flandre;
                now->Right->key = now->Flandre;

                now->Left->Flandre = now->Flandre;
                now->Right->Flandre = now->Flandre;

                now->Flandre = 0;
            }
            now->key = min (now->Left->key, now->Right->key);
            int res = INF;
            if (l <= now->Mid)
                res = Query (now->Left, l, min (now->Mid, r));
            if (r > now->Mid)
                res = min (res, Query (now->Right, max (now->Mid + 1, l), r));
            return res;
        }

        void Change_Section_Maxn (Segment_Tree_Date *&now, int l, int r, int to)
        {
            if (l <= now->l && now->r <= r)
            {
                now->Flandre = to;
                now->key = to;
                return ;
            }
            if (now->Flandre)
            {
                now->Left->key = now->Flandre;
                now->Right->key = now->Flandre;

                now->Left->Flandre = now->Flandre;
                now->Right->Flandre = now->Flandre;

                now->Flandre = 0;
            }
            if (l <= now->Mid)
                Change_Section_Maxn (now->Left, l, min (now->Mid, r), to);
            if (r > now->Mid)
                Change_Section_Maxn (now->Right, max (now->Mid + 1, l), r, to);
            now->key = min (now->Left->key, now->Right->key);
        }
};

Segment_Tree_Type Tree;

int M;
bool is_exist[Max];

int main (int argc, char *argv[])
{
    read (N);
    read (K);
    for (int i = 1; i <= N; i++)
        read (number[i]);
    int type, x, y, z;
    is_exist[1] = true;
    int now_1, now_2;
    Tree.Build (Root, 1, N, 1);
    register bool flag;
    for (read (M); M--; )
    {
        flag = false;
        read (type);
        read (x);
        read (y);
        if (type == 1)
        {
            read (z);
            now_1 = ceil (x * 1.0 / N);
            now_2 = ceil (y * 1.0 / N);
            for (int pos = now_1; pos <= now_2; pos++)
                if (!is_exist[pos])
                {
                    Tree.Build (Root, N * (pos - 1) + 1, N * pos, pos);
                    flag = true;
                    is_exist[pos] = true;
                }
            if (flag)
                Tree.Whole_Updata (Root, N * (now_1 - 1) + 1, N * now_2);
            Tree.Change_Section_Maxn (Root, x, y, z);
        }
        else
        {
            now_1 = ceil (x * 1.0 / N);
            now_2 = ceil (y * 1.0 / N);
            for (int pos = now_1; pos <= now_2; pos++)
                if (!is_exist[pos])
                {
                    Tree.Build (Root, N * (pos - 1) + 1, N * pos, pos);
                    flag = true;
                    is_exist[pos] = true;
                }
            if (flag)
                Tree.Whole_Updata (Root, N * (now_1 - 1) + 1, N * now_2);
            printf ("%d\n", Tree.Query (Root, x, y));
        }
    }
    return 0;
}
时间: 2024-10-12 08:06:34

(WAWAWAWAWAWAW) G. Periodic RMQ Problem的相关文章

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

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

思路: (我也不知道这是不是正解) ST表预处理出来原数列的两点之间的min 再搞一个动态开节点线段树 节点记录ans 和标记 lazy=-1 当前节点的ans可用  lazy=0 没被覆盖过 else 区间覆盖 push_up的时候要注意好多细节,, 数组尽量往大开 //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const in

Rmq Problem

大视野——3339: Rmq Problem Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1192  Solved: 620[Submit][Status][Discuss] Description Input Output Sample Input 7 50 2 1 0 1 3 21 32 31 43 62 7 Sample Output 30324 HINT Source By Xhr 思路: 对于这个题似乎暴力不好打,而且似乎强制在线操作

【BZOJ】【3339】Rmq Problem

离线+线段树 Orz Hzwer,引用题解: 这一题在线似乎比较麻烦 至于离线.. 首先按照左端点将询问排序 然后一般可以这样考虑 首先如何得到1-i的sg值呢 这个可以一开始扫一遍完成 接着考虑l-r和l+1-r的答案有何不同 显然是l-next[l]-1这一段所有sg值大于a[l]的变为a[l] 这一步如果暴力修改的话只有30分 但是修改区间我们可以想到线段树,这样就能a了 晚上写题有点晕……忘了把当前时刻now置为q[i].l了,这种傻逼错误居然也犯…… 1 /**************

【BZOJ3489】A simple rmq problem kd-tree

[BZOJ3489]A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直接输出0.我会采取一些措施强制在线. Input 第一行为两个整数N,M.M是询问数,N是序列的长度(N<=100000,M<=200000) 第二行为N个整数,描述这个序列{ai},其中所有1<=ai<=N 再下面M行,每

bzoj 3339: Rmq Problem

3339: Rmq Problem Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1270  Solved: 666[Submit][Status][Discuss] Description Input Output Sample Input 7 5 0 2 1 0 1 3 2 1 3 2 3 1 4 3 6 2 7 Sample Output 3 0 3 2 4 HINT Source By Xhr 嗯,莫队 懒得敲线段树,毕竟线段树比较短 #

【bzoj3339】Rmq Problem

[bzoj3339]Rmq Problem Description Input Output Sample Input 7 50 2 1 0 1 3 21 32 31 43 62 7 Sample Output 30324 HINT 分析 离线算法. 对于[l,r]区间的询问,我们可以线性求出来,然后考虑[l+1,r]区间有什么不同,在a[l]下一次出现的位置之前,所有大于a[l]的mex,都变成是a[l],因为 [l+1,a[l]下一次出现的位置-1],这个区间内没有a[l]了,大于它的数当然

【BZOJ】【3489】A simple rmq problem

KD-Tree(乱搞) Orz zyf教给蒟蒻做法 蒟蒻并不会这题正解……(可持久化树套树?...Orz 对于每个点,我们可以求出pre[i],nex[i],那么询问的答案就是:求max (a[i]),其中 i 满足$ ( pre[i]<ql \ and \ nex[i]>qr\ and\ i \in [ql,qr] ) $ 然后我们以(i,pre[i],nex[i])为坐标……将所有点抽象到三维空间中,每次查询就相当于是一次区域求最值! 这题我的感受: 因为前面做了两道区域求和的……然后思路

【题解】P4137 Rmq Problem(莫队)

[题解]P4137 Rmq Problem(莫队) 其实这道题根本就不用离散化! 因为显然有\(mex\)值是\(\le 2\times 10^5\)的,所以对于大于\(2\times 10^5\)的数我们可以忽略. 然后直接莫队算就是的,开一个\(2e5\)的桶 若一个比答案小的值的桶为\(0\)了:答案更新为它 若这个\(mex\)的桶突然有值了:暴力枚举答案变大,第一个桶里没值的就是答案,更新. 有小伙伴会问,这复杂度不上天了?其实不然.移动\(ans\)的总复杂度(好像)是\(O(n\s