codeforces 803 G. Periodic RMQ Problem(線段樹動態開點)

題目鏈接:https://codeforces.com/contest/803/problem/G

思路:動態開點模板題

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <cmath>
#include <cctype>
#include <unordered_map>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll inff = 0x3f3f3f3f3f3f3f3f;
#define FOR(i,a,b) for(int i(a);i<=(b);++i)
#define FOL(i,a,b) for(int i(a);i>=(b);--i)
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define ss(a) scanf("%s",a)
#define mod ll(1e9+7)
#define pb push_back
#define eps 1e-7
#define lc d<<1
#define rc d<<1|1
#define Pll pair<ll,ll>
#define P pair<int,int>
#define pi acos(-1)
int stmin[100008][20],n,q,k,cnt,id,x,y,z,Log[100008];
struct as{
    int l,r,ma,ls,rs,lz;
    as(){}
    as(int L,int R,int LS,int RS,int MI,int LZ){l=L;r=R;ls=LS;rs=RS;ma=MI;lz=LZ;}
}tr[100008<<6];
void st()
{
    Log[0]=-1;
    for(int i=1;i<=n;i++) Log[i]=Log[i>>1]+1;
    for(int j=1;(1<<j)<=n;j++)
     for(int i=1;i+(1<<j)-1<=n;i++)
      stmin[i][j]=min(stmin[i][j-1],stmin[i+(1<<(j-1))][j-1]);
}
int query(int l,int r)
{
    int x=Log[r-l+1];
    return min(stmin[l][x],stmin[r-(1<<x)+1][x]);
}
int Query(int l,int r)
{
    if(r-l+1>=n) return query(1,n);
    l%=n,r%=n;
    if(l==0) l+=n;
    if(r==0) r+=n;
    if(l<=r) return query(l,r);
    else return min(query(l,n),query(1,r));
}
void build(int d)
{
     int mid=(tr[d].l+tr[d].r)>>1;
     if(tr[d].ls==-1){
        tr[d].ls=++cnt;
        tr[cnt]=as(tr[d].l,mid,-1,-1,Query(tr[d].l,mid),-1);
     }
     if(tr[d].rs==-1){
        tr[d].rs=++cnt;
        tr[cnt]=as(mid+1,tr[d].r,-1,-1,Query(mid+1,tr[d].r),-1);
     }
}
void push(int d){tr[d].ma=min(tr[tr[d].ls].ma,tr[tr[d].rs].ma);}
void pushh(int d)
{
    build(d);
    if(tr[d].lz==-1) return;
    tr[tr[d].ls].ma=tr[d].lz;tr[tr[d].rs].ma=tr[d].lz;
    tr[tr[d].ls].lz=tr[d].lz;tr[tr[d].rs].lz=tr[d].lz;
    tr[d].lz=-1;
}
void add(int d,int l,int r,int pos)
{
    if(tr[d].l==l&&tr[d].r==r) {tr[d].ma=pos;tr[d].lz=pos;return;}
    pushh(d);
    int mid=(tr[d].l+tr[d].r)>>1;
    if(mid>=r)  add(tr[d].ls,l,r,pos);
    else if(l>mid)  add(tr[d].rs,l,r,pos);
    else  add(tr[d].ls,l,mid,pos),add(tr[d].rs,mid+1,r,pos);
    push(d);
}
int query(int d,int l,int r)
{
    if(tr[d].l==l&&tr[d].r==r)  {return tr[d].ma;}
    pushh(d);
    int mid=(tr[d].l+tr[d].r)>>1;
    if(mid>=r)  return query(tr[d].ls,l,r);
    else if(l>mid)  return query(tr[d].rs,l,r);
    else  return min(query(tr[d].ls,l,mid),query(tr[d].rs,mid+1,r));
}
int main()
{
    cin.tie(0);
    cout.tie(0);
    cin>>n>>k;
    FOR(i,1,n) si(stmin[i][0]);
    st();cin>>q;
    tr[++cnt]=as(1,n*k,-1,-1,query(1,n),-1);
    while(q--)
    {
        si(id);
        if(id==1) si(x),si(y),si(z),add(1,x,y,z);
        else si(x),si(y),printf("%d\n",query(1,x,y));
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章