首页 > 其他分享 >G. Periodic RMQ Problem

G. Periodic RMQ Problem

时间:2022-10-28 16:47:14浏览次数:75  
标签:RMQ return int tr mid Periodic query Problem tag

G. Periodic RMQ Problem

题目大意

给你一个序列\(a\) 让你支持

\(1\) \(l\) \(r\) \(x\) 区间赋值

\(2\) \(l\) \(r\) 询问区间最小值

我们觉得这个问题太水了,所以我们不会给你序列\(a\)

而是给你序列一个长度为\(n\) 的序列\(b\) ,把\(b\) 复制粘贴\(k\) 次就可以得到\(a\)

\(n\le10^5,k\le10^4,q\le10^5,b_i\le10^9\)

\(1\le l\le r\le n\times k\)

分析

题目不难,我们就来顺序的捋一下我们要干嘛。

两个操作,区间赋值与询问区间最小值。

但是区间太大啦,是\(10^9\)的数量级。一般线段树区间这么大,那我们肯定要上动态开点了。

并且虽然是求最小值,但是其构成是有规律的,它是由k个长度为n的数组拼接而成的。

也就是说,如果我们要求一段区间的最小值,如果该区间,我们的线段树中并未开出对应区间,则代表的是,该区间的最小值是原来数组中对应位置的最小值。

因此,我们要能快速的求出一段静态区间的最值,想到了什么?没错,ST表此时就可以发挥作用。

总的时间复杂度是\(O(q\log(nk)\log(n))\)

AC_code

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false); cin.tie(0), cout.tie(0)
using namespace std;
const int N = 1e5 + 10,inf = 0x3f3f3f3f;

template<typename T=int,const int N=18,typename Comp=less<T>>//Comp则是设立比较方式
struct ST
{
    T ans[N][1<<N];int n,lg[1<<N],k;
    void init(T*a,int n_){
        n=n_;
        lg[0]=-1;for(int i=1;i<=n;i++)lg[i]=lg[i>>1]+1;
        for(int i=1;i<=n;i++)ans[0][i]=*++a;
        for(int i=1;i<N;i++)
            for(int j=1;j+(1<<i)<=n+1;j++)
                ans[i][j]=max(ans[i-1][j],ans[i-1][j+(1<<(i-1))],Comp());
    }
    int query(const int l,const int r){
        k=31-__builtin_clz(r-l+1);
        return max(ans[k][l],ans[k][r-(1<<k)+1],Comp());
    }
};

ST<int,17,greater<int>> st;

struct Node
{
    int l,r;
    int mi,tag;
}tr[N<<6];
int a[N];
int idx,root;
int n,k,q;

int get(int l,int r)
{
    if(r-l+1>=n) return st.query(1,n);
    if(r%n==0) return st.query(l%n==0?n:l%n,n);
    if(l%n==0) return min(a[n],st.query(1,r%n));
    if(l/n!=r/n) return min(st.query(l%n,n),st.query(1,r%n));
    return st.query(l%n,r%n);
}

int init(int u,int l,int r)
{
    tr[u].tag = tr[u].l = tr[u].r = 0;
    tr[u].mi = get(l,r);
    return u;
}

void pushup(int u,int l,int r)
{
    int L,R,mid = l + r >> 1;
    if(!tr[u].l) L = get(l,mid);
    else L = tr[tr[u].l].mi;
    if(!tr[u].r) R = get(mid+1,r);
    else R = tr[tr[u].r].mi;
    tr[u].mi = min(L,R);
}

void pushdown(int u,int l,int r)
{
    int mid = l + r >> 1;
    if(!tr[u].l) tr[u].l = init(++idx,l,mid);
    if(!tr[u].r) tr[u].r = init(++idx,mid+1,r);
    auto &root = tr[u],&left = tr[tr[u].l],&right = tr[tr[u].r];
    if(root.tag)
    {
        left.tag = root.tag;
        right.tag = root.tag;
        left.mi = root.tag;
        right.mi = root.tag;
        root.tag = 0;
    }
}

void modify(int &u, int l, int r, int L, int R, int k) {
    if(R<l||L>r) return ;
    if(!u) u = init(++idx,l,r);
    if(L <= l && R >= r) {
        tr[u].mi = k;
        tr[u].tag = k;
        return ;
    }
    pushdown(u, l, r);
    int mid = l + r >> 1;
    modify(tr[u].l, l, mid, L, R, k);modify(tr[u].r, mid + 1, r, L, R, k);
    pushup(u,l,r);
}

int query(int u,int l,int r,int L,int R)
{
    if(R<l||L>r) return inf;
    if(L<=l&&r<=R) 
    {
        if(!u) return get(l,r);
        return tr[u].mi;
    }
    pushdown(u,l,r);
    int mid = l + r >> 1;
    return min(query(tr[u].l,l,mid,L,R),query(tr[u].r,mid+1,r,L,R));
}

int main()
{
    ios;
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    st.init(a,n);
    cin>>q;
    while(q--)
    {
        int op,l,r,x;cin>>op>>l>>r;
        if(op==1) 
        {
            cin>>x;
            modify(root,1,n*k,l,r,x);
        }
        else cout<<query(root,1,n*k,l,r)<<'\n';
    }
    return 0;
}

标签:RMQ,return,int,tr,mid,Periodic,query,Problem,tag
From: https://www.cnblogs.com/aitejiu/p/16836565.html

相关文章

  • [COMP2121] Bertrand's Ballot Problem
    DescriptionSupposethereare$x$votesfor$A$and$y$notesfor$B$,and$x>y$.Howmanysequencesarethereofrevealingthevotessuchthatthenumbervote......
  • Problem In Developing
    写了一段代码后发现无法通过测试思路1:首先review这段代码,思考可能会出现什么问题需要及时提交commit思路2:回退代码后重写思路3:找到错误信息,调试bug......
  • D. Problem with Random Tests
    传送门题意:给出一个字符串,然后,从这个字符串中取两个子串s1,s2,要求两个字符串的或最大思路:首先,先去s1从第一个非0开始取整段,记录第一个非0的位置为p1,因为或位数......
  • [React] useEffect - problem: dependency is Object
    Let'ssaywehaveasimpleapplooklikethis:import{useEffect,useState}from"react";functionuseFetch(config){console.log("useFetchcall");cons......
  • 关于 problem.conf
    基本设置problem.conf中一行只能含有一个设置(不然可能会出现奇怪的错误?)use_builtin_judger大多数题的problem.conf里都要有use_builtin_judgeron这句话,这表示您需......
  • 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......
  • 中国(北方)大学生程序设计训练赛(第一周)(Problem E: Water Problem-矩阵快速幂)
    已知f(1),f(2),n,f(n+1)=f(n)+f(n-1)+sin(n*Pi/2),(n>=2)求f(n)矩阵快速幂,周期乘4个矩阵#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#incl......
  • BZOJ 2302([HAOI2011]Problem c-组合数学)
    Description给n个人安排座位,先给每个人一个1~n的编号,设第i个人的编号为ai(不同人的编号可以相同),接着从第一个人开始,大家依次入座,第i个人来了以后尝试坐到ai,如果ai被占据了,就......
  • RockerMQ启动Broke报错 /Library/Internet: No such file or directory
    背景相信大家看到这个文章对消息服务器已经不陌生了,笔者也是在平日无聊想着自己编写一套关于RockerMQ的消息灰度框架的时候,准备本地搭建一个RockerMQ服务环境时遇到了一......
  • ARC139F Many Xor Optimization Problems
    题意:给定\(n,m\),求\(n\)个\([0,2^m)\)的数的最大异或和的和。瞎扯:考虑线性基,考虑消元后的,显然唯一,最大异或和为基内所有数的异或和。考虑大小为\(k\)的基方案数为......