zoukankan      html  css  js  c++  java
  • Codeforces 803 G. Periodic RMQ Problem

    题目链接:http://codeforces.com/problemset/problem/803/G


    大致就是线段树动态开节点。

    然后考虑到如果一个点还没有出现过,那么这个点显然未被修改,就将这个点所代表的区间定位到原序列中,利用ST表查一下区间最小值就可以了。

    定位:

    1 llg minn(llg l,llg r)
    2 {
    3     if(r-l+1>=n) return mt;
    4     l%=n;if(!l) l=n;
    5     r%=n;if(!r) r=n;
    6     if(l>r) return min(gw(l,n),gw(1,r));
    7     else return gw(l,r);
    8 }

    其中${gw(l,r)}$表示原序列${[l,r]}$中元素的最小值。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstdio>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<cstring>
      7 #include<queue>
      8 #include<vector>
      9 #include<map>
     10 using namespace std;
     11 #define llg int
     12 #define inf 0x7fffffff
     13 #define maxn 500010
     14 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
     15 llg ST[maxn][20],mt=inf,n,k,Q,pre[maxn],cnt;
     16 
     17 struct point
     18 {
     19     llg lc,rc,l,r,set,val;
     20 }po[maxn*30];
     21 
     22 inline llg getint()
     23 {
     24     llg w=0,q=0; char c=getchar();
     25     while((c<'0' || c>'9') && c!='-') c=getchar();
     26     if (c=='-')  q=1, c=getchar(); while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
     27     return q ? -w : w;
     28 }
     29 
     30 llg gw(llg l,llg r)
     31 {
     32     int k=pre[r-l+1];
     33     return min(ST[l][k],ST[r-(1<<k)+1][k]);
     34 }
     35 
     36 llg minn(llg l,llg r)
     37 {
     38     if(r-l+1>=n) return mt;
     39     l%=n;if(!l) l=n;
     40     r%=n;if(!r) r=n;
     41     if(l>r) return min(gw(l,n),gw(1,r));
     42     else return gw(l,r);
     43 }
     44 
     45 void make_st()
     46 {
     47     for(llg i=2;i<=n;i++) pre[i]=pre[i>>1]+1;
     48     for(llg i=1;i<=n;i++) ST[i][0]=getint();
     49     for(llg i=1;i<=n;i++) mt=min(mt,ST[i][0]);
     50     for(llg i=2;i<=n;i++) pre[i]=pre[i>>1]+1;
     51     for(llg j=1;j<=17;j++)
     52         for(llg i=1,u=(1<<j),p=(u>>1);i+u-1<=n;i++)
     53             ST[i][j]=min(ST[i][j-1],ST[i+p][j-1]);
     54     cnt=1,po[1].l=1,po[1].r=n*k,po[1].val=mt;
     55 }
     56 
     57 llg new_po(llg l,llg r)
     58 {
     59     llg o=++cnt;
     60     po[o].val=minn(l,r);
     61     po[o].l=l,po[o].r=r;
     62     return o;
     63 }
     64 
     65 void update(llg o)
     66 {
     67     if (po[o].l==po[o].r) return ;
     68     po[o].val=inf;
     69     if (po[o].lc) po[o].val=min(po[o].val,po[po[o].lc].val);
     70     else
     71     {
     72         po[o].lc=cnt+1;
     73         new_po(po[o].l,(po[o].l+po[o].r)/2);
     74         po[o].val=min(po[o].val,po[po[o].lc].val);        
     75     }
     76     if (po[o].rc) po[o].val=min(po[o].val,po[po[o].rc].val);
     77     else
     78     {
     79         po[o].rc=cnt+1;
     80         new_po((po[o].l+po[o].r)/2+1,po[o].r);
     81         po[o].val=min(po[o].val,po[po[o].rc].val);
     82     }
     83 }
     84 
     85 void pushdown(llg o)
     86 {
     87     llg l=po[o].l,r=po[o].r,lc=po[o].lc,rc=po[o].rc,mid=(l+r)>>1;
     88     if (!po[o].set || l==r) return ;
     89     if (!lc)
     90     {
     91         lc=cnt+1;
     92         new_po(l,mid);
     93     }
     94     if (!rc) 
     95     {
     96         rc=cnt+1;
     97         new_po(mid+1,r);
     98     }
     99     po[lc].set=po[rc].set=po[lc].val=po[rc].val=po[o].set;
    100     po[o].set=0;
    101     po[o].lc=lc;
    102     po[o].rc=rc;
    103     return ;
    104 }
    105 
    106 void modify(llg o,llg l,llg r,llg L,llg R,llg v)
    107 {
    108     pushdown(o);
    109     if (o==0) o=new_po(l,r);    
    110     llg mid=(l+r)>>1;
    111     if (l>=L && r<=R)
    112     {
    113         po[o].val=v;
    114         po[o].set=v;
    115         return ;
    116     }
    117     if (mid>=L) 
    118     {
    119         llg son=po[o].lc;
    120         if (po[o].lc==0) po[o].lc=cnt+1;
    121         modify(son,l,mid,L,R,v);
    122     }
    123     if (mid<R)
    124     {
    125         llg son=po[o].rc;
    126         if (po[o].rc==0) po[o].rc=cnt+1;
    127         modify(son,mid+1,r,L,R,v);
    128     }
    129     update(o);
    130 }
    131 
    132 llg query(llg o,llg l,llg r,llg L,llg R)
    133 {
    134     pushdown(o);
    135     if (o==0) o=new_po(l,r);
    136     if (l>=L && r<=R) return po[o].val;
    137     llg mid=(l+r)>>1,ans=inf;
    138     if (mid>=L)
    139     {
    140         llg son=po[o].lc;
    141         if (po[o].lc==0) po[o].lc=cnt+1;
    142         ans=min(ans,query(son,l,mid,L,R));
    143     }
    144     if (mid<R)
    145     {
    146         llg son=po[o].rc;
    147         if (po[o].rc==0) po[o].rc=cnt+1;
    148         ans=min(ans,query(son,mid+1,r,L,R));
    149     }
    150     return ans;
    151 }
    152 
    153 int main()
    154 {
    155     yyj("seg");
    156     cin>>n>>k;
    157     make_st();
    158     llg T=n*k;
    159     cin>>Q;
    160     while (Q--)
    161     {
    162         llg ty=getint(),l=getint(),r=getint();
    163         if (ty==1) 
    164             modify(1,1,T,l,r,getint());
    165         else 
    166             printf("%d
    ",query(1,1,T,l,r));
    167     }
    168     return 0;
    169 }
  • 相关阅读:
    BZOJ_2039_[2009国家集训队]employ人员雇佣_ 最小割
    BZOJ_4238_电压_树上差分+dfs树
    BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay
    BZOJ_3048_[Usaco2013 Jan]Cow Lineup _双指针
    BZOJ_3689_异或之_可持久化Trie+堆
    BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表
    BZOJ_3675_[Apio2014]序列分割_斜率优化
    BZOJ_4518_[Sdoi2016]征途_斜率优化
    BZOJ_1407_[Noi2002]Savage_EXGCD
    [转载]ubuntu常用命令
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6794691.html
Copyright © 2011-2022 走看看