首页 > 其他分享 >CF803G Periodic RMQ Problem

CF803G Periodic RMQ Problem

时间:2022-11-20 18:11:59浏览次数:61  
标签:RMQ return val minn int mid Periodic CF803G lz

这题很妙,当时用CD的方法,写平衡树,但是吧没有领会精神,写了200多行,发现前驱后继又不合法的情况,好像要写12种情况,就不想写了。然后就突然明白线段树做法了。。。

介绍一种线段树做法:

本质思想是一样的,可能实现上优雅一点?

本质思想:动态开点,最多会有十万个点,完全可以,如果一段区间被覆盖一次之后,那么直接维护,如果没有被覆盖,我们需要在原序列上查询。

如果需要查询的区间在同一个周期内,直接查,如果大于一个周期,就是最小值,如果跨越两个区间,就很尴尬,可以将序列复制一遍,然后r = l + len - 1,查询。st表维护一下。会发现如果儿子没有被覆盖,那么一定是空。如果是空,那么直接查询,魔改pushup就行。

查询的话,如果说目前节点的区间为空,我们需要查询这个区间对应的原序列,左端点取max,右端点取min就行。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
const int INF = 1 << 30;
int n,k,q,b[N],rt,st[N << 1][21];
void St_pre(){
    memset(st,0x3f,sizeof(st));
    for(int i = 1;i <= n;++i)st[i][0] = b[i];
    for(int i = n + 1;i <= 2 * n;++i)st[i][0] = b[i - n];
    for(int i = 1;i <= 20;++i)for(int j = 1;j + (1 << i) - 1 <= n * 2;++j)st[j][i] = min(st[j][i - 1],st[j + (1 << (i - 1))][i - 1]);
}
int St_ask(int l,int r){
    int ed = log2(r - l + 1);
    return min(st[l][ed],st[r - (1 << ed) + 1][ed]);
}
int Ask(int l,int r){
    int len = r - l + 1;
    if(len >= n){
        return St_ask(1,n);
    }else{
        l = (l % n == 0) ? n : (l % n);
        return St_ask(l,l + len - 1);
    }
}
struct Segment{
    #define lson(p) t[p].ls
    #define rson(p) t[p].rs
    struct node{
        int ls,rs,minn,lz;
        node(){lz = 0;minn = INF;}
    }t[N * 50];
    int tot = 0;
    Segment(){tot = 0;}
    void pushup(int p,int l,int r){
        int lw = INF,rw = INF,mid = l + r >> 1;
        if(lson(p))lw = t[lson(p)].minn;
        else lw = Ask(l,mid);
        if(rson(p))rw = t[rson(p)].minn;
        else rw = Ask(mid + 1,r);
        t[p].minn = min(lw,rw);
    }
    void tag(int &p,int val){
        if(!p)p = ++tot;
        t[p].lz = val;
        t[p].minn = val;
    }
    void pushdown(int p){
        if(!t[p].lz)return;
        tag(lson(p),t[p].lz);
        tag(rson(p),t[p].lz);
        t[p].lz = 0;
    }
    void modify(int &p,int L,int R,int l,int r,int val){
        if(!p)p = ++tot;
        if(l <= L && r >= R){
            tag(p,val);
            return;
        }    
        pushdown(p);
        int mid = L + R >> 1;
        if(l <= mid)modify(lson(p),L,mid,l,r,val);
        if(r > mid)modify(rson(p),mid + 1,R,l,r,val);
        pushup(p,L,R);
    }
    int query(int p,int L,int R,int l,int r){
        if(l > r)return INF;
        if(!p)return Ask(max(l,L),min(r,R));
        if(l <= L && r >= R)return t[p].minn;
        int mid = L + R >> 1;
        pushdown(p);
        int res = 1 << 30;
        if(l <= mid)res = min(res,query(lson(p),L,mid,l,r));
        if(r > mid)res = min(res,query(rson(p),mid + 1,R,l,r));
        return res;
    }
}S;
int main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>n>>k;
    for(int i = 1;i <= n;++i)cin>>b[i];
    St_pre();
    cin>>q;
    for(int i = 1;i <= q;++i){
        int opt,l,r,x;
        cin>>opt>>l>>r;
        if(opt & 1){
            cin>>x;
            S.modify(rt,1,n * k,l,r,x);
        }else cout<<S.query(rt,1,n * k,l,r)<<"\n";
    }
    return 0;
}

标签:RMQ,return,val,minn,int,mid,Periodic,CF803G,lz
From: https://www.cnblogs.com/zasdcn/p/16909120.html

相关文章

  • ST表&倍增&RMQ问题
    ST表,SparseTable,是解决区间最值问题,及RMQ问题的工具,利用倍增思想,O(N*log2(N))预处理,O(1)查询。设f[i][j]表示从i开始的2^j个数的最值,初始化f[i][0]=a[i],对于处理f数组,......
  • rmq板子
    typedeflonglongLL;constexprinlineintlg2(LLx){returnsizeof(LL)*8-1-__builtin_clzll(x);}template<typenameT,size_tN,size_tK>structRangeQ......
  • G. Periodic RMQ Problem
    G.PeriodicRMQProblem题目大意给你一个序列\(a\)让你支持\(1\)\(l\)\(r\)\(x\)区间赋值\(2\)\(l\)\(r\)询问区间最小值我们觉得这个问题太水了,所以我们......
  • POJ 3264(STRMQ)
    forj:=1toln(n)/ln(2)  fori:=1ton-(1shlj)+1do    f[i,j]:=min(f[i,j-1],f[i+(1shl(j-1),j-1];f[l,r]:=min(f[l,j],f[r-(1shlj)+1,j];j=ln(r-l+1......
  • RockerMQ启动Broke报错 /Library/Internet: No such file or directory
    背景相信大家看到这个文章对消息服务器已经不陌生了,笔者也是在平日无聊想着自己编写一套关于RockerMQ的消息灰度框架的时候,准备本地搭建一个RockerMQ服务环境时遇到了一......
  • RMQ
    时间复杂度处理O(nlogn)查询O(1)#include<bits/stdc++.h>usingnamespacestd;#defineintlonglong#defineullunsignedlonglong#defineendl"\n"#definesf......
  • RMQ求LCA
    RMQ求LCA:使用欧拉序点击查看代码#include<stdio.h>#include<string.h>#include<ctype.h>constintIN_SIZE=200005,OUT_SIZE=200005;charinbuf[IN_SIZE+......
  • 12th 2022/7/11 RMQ专题复习
    分为三类吧线段树这种数据结构挺有用的,使用范围是时间,看着办嘛,\(O(n\logn)\)的算法,修改加入查询都是\(O(\logn)\)然后建树\(O(n\logn)\)看着办大概思路就是将一个......
  • And RMQ 势能线段树-用剪枝+单点修改实现区间修改
    https://codeforces.com/gym/103107/problem/AA.AndRMQtimelimitpertest3secondsmemorylimitpertest512megabytesinputstandardinputoutputstan......
  • RockerMQ (一)
    目录linux安装linux安装1.下载二进制安装包到~目录下2.解压unziprocketmq-all-4.4.0-bin-release.zip3.RocketMQ默认分配的JVM内存比较大,而虚拟机没有那么大的配......