1. 程式人生 > >LOJ.6284.數列分塊入門8(分塊)

LOJ.6284.數列分塊入門8(分塊)

統計 完整 入門 source inline set min 一個數 tdi

題目鏈接

\(Description\)

給出一個長為n的數列,以及n個操作,操作涉及區間詢問等於一個數c的元素,並將這個區間的所有元素改為c。

\(Solution\)

模擬一些數據可以發現,詢問後一整段都會被修改,幾次詢問後數列可能只剩下幾段不同的區間了。
那麽還是暴力,每個塊維護的是整個塊是否僅被一種權值覆蓋。查詢時對於相同權值的塊就可以O(1)統計;否則暴力統計並修改答案;不完整的塊暴力。
這樣看似最差情況下每次需要O(n)的時間,但實際遠遠到不了
假設初始序列都是同一個值,那麽查詢需要O(sqrt(n)),如果這時進行區間修改,那麽最多會破壞首尾兩個塊的標記
所以只能使後面的詢問至多多2個塊的暴力時間,所以均攤每次操作復雜度為O(sqrt(n))

換句話說,要想讓一個操作耗費O(n)的時間,要先花費sqrt(n)個操作修改數列
----by hzwer

#include <cmath>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=1e5+5,MAXIN=1e6;

int n,size,sizen,A[N],tag[2000],bel[N],L[2000
],R[2000]; bool cover[2000]; char IN[MAXIN],*SS=IN,*TT=IN; inline int read() { int now=0,f=1;register char c=gc(); for(;!isdigit(c);c=gc()) if(c=='-') f=-1; for(;isdigit(c);now=now*10+c-'0',c=gc()); return now*f; } int Count(int l,int r,int v) { int res=0; for(int i=l; i<=r; ++i) if
(A[i]==v) ++res; else A[i]=v; return res; } void Reset(int p,int l,int r,int vbef,int v) {//Reset [L(p),l)&&(r,R(p)] to vbef,[l,r] to v for(int i=L[p]; i<l; ++i) A[i]=vbef; for(int i=l; i<=r; ++i) A[i]=v; int t=std::min(n,R[p]); for(int i=r+1; i<=t; ++i) A[i]=vbef; cover[p]=0; } int Get_scatter(int l,int r,int v) { if(cover[bel[l]]) if(tag[bel[l]]==v) return r-l+1; else Reset(bel[l],l,r,tag[bel[l]],v); else return Count(l,r,v); return 0; } int Query(int l,int r,int v) { int res=Get_scatter(l,std::min(r,R[bel[l]]),v); if(bel[l]!=bel[r]) res+=Get_scatter(L[bel[r]],r,v); for(int i=bel[l]+1; i<bel[r]; ++i) if(cover[i]) if(tag[i]==v) res+=bel[l]==bel[n]?sizen:size; else tag[i]=v; else res+=Count(L[i],R[i],v), cover[i]=1, tag[i]=v; return res; } int main() { n=read(), size=sqrt(n); for(int i=1; i<=n; ++i) bel[i]=(i-1)/size+1, A[i]=read(); for(int i=1; i<=bel[n]; ++i) L[i]=(i-1)*size+1,R[i]=i*size; sizen=n-(bel[n]-1)*size; for(int l,r,c,i=1; i<=n; ++i) l=read(), r=read(), c=read(), printf("%d\n",Query(l,r,c)); return 0; }

LOJ.6284.數列分塊入門8(分塊)