题目链接: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\n",query(1,1,T,l,r)); 167 } 168 return 0; 169 }