洛谷.3709.大爺的字符串題(莫隊 區間眾數)
阿新 • • 發佈:2018-09-06
efi void sdi str gis sqrt algo .org ans
題目鏈接
這不就是個求區間眾數的次數麽,還不強制在線,值域分塊與莫隊都可做,用的莫隊。
發現從區間減掉一個數,如果它是答案,好像很難處理?
但是答案要麽不變要麽就-1啊,記一下出現x次的有多少個數不就行了。
//1630ms 6.86MB #include <cmath> #include <cstdio> #include <cctype> #include <algorithm> #define gc() getchar() const int N=2e5+5; int n,m,A[N],ref[N],bel[N],Ans,tm[N],cnt[N],ans[N]; struct Quries { int l,r,id; // Quries() {} // Quries(int l,int r,int id):l(l),r(r),id(id) {}//寫了竟然影響下面了。。 bool operator <(const Quries &x)const{ return bel[l]==bel[x.l]?r<x.r:bel[l]<bel[x.l]; } }q[N]; inline int read() { int now=0;register char c=gc(); for(;!isdigit(c);c=gc()); for(;isdigit(c);now=now*10+c-'0',c=gc()); return now; } int Find(int x,int r) { int l=1,mid; while(l<r) if(ref[mid=l+r>>1]<x) l=mid+1; else r=mid; return l; } inline void Add(int p) { --cnt[tm[p]], Ans=std::max(Ans,++tm[p]), ++cnt[tm[p]]; } inline void Subd(int p) { if(!--cnt[tm[p]] && Ans==tm[p]) --Ans; --tm[p], ++cnt[tm[p]]; } int main() { n=read(), m=read(); int size=sqrt(n); for(int i=1; i<=n; ++i) bel[i]=i/size; for(int i=1; i<=n; ++i) ref[i]=A[i]=read(); std::sort(ref+1,ref+1+n); int cnt=1; for(int i=2; i<=n; ++i) if(ref[i]!=ref[i-1]) ref[++cnt]=ref[i]; for(int i=1; i<=n; ++i) A[i]=Find(A[i],cnt); for(int i=1; i<=m; ++i) q[i]=(Quries){read(),read(),i}; std::sort(q+1,q+1+m); for(int l=1,r=0,i=1; i<=m; ++i) { int ln=q[i].l,rn=q[i].r; while(l<ln) Subd(A[l++]); while(l>ln) Add(A[--l]); while(r<rn) Add(A[++r]); while(r>rn) Subd(A[r--]); ans[q[i].id]=Ans; } for(int i=1; i<=m; ++i) printf("%d\n",-ans[i]); return 0; }
洛谷.3709.大爺的字符串題(莫隊 區間眾數)