Solutions of Mode - MarisaOJ: Marisa Online Judge

Solutions of Mode

Select solution language

Write solution here.


User Avatar lenhanbo    Created at    20 likes

Ta sẽ chia dãy thành n block kế nhau. Gọi mode(i,j) là đáp án cho 1 dãy gồm các block liên tiếp từ block i đến block j. Ta có thể tính được đáp án cho 1 dãy gồm nhiều block riêng tiếp trong o(n × n). Gọi id(i) là chỉ số block của phần tử i. Ta có 2 nhận xét như sau : 1. "Đáp án sẽ không vượt quá n × 2 + mode(id(l)+1,id(r)1)". Bạn đọc có thể tự chứng minh. 2. "Đáp án hoặc là mode(id(l)+1,id(r)1) hoặc là số lần xuất hiện trong đoạn lr của 1 phần tử nào đấy trong 2 phần dư". Vậy thì từ nhận xét, ta có thuật toán như sau : Đầu tiên, ta cần tính trước mode(i,j) cho mọi cặp chỉ số block i,j (i<j). Với mỗi truy vấn ta sẽ có 2 dạng : 1. lr thuộc 2 block kề nhau hoặc chung 1 block, ta có thể duyệt trâu từ l đến r rồi dùng 1 mảng đếm để tìm đáp án. 2. Giữa lr có ít nhất 1 block : + Đầu tiên, ta sẽ đánh số cho mỗi phần tử a(i) là thứ tự xuất hiện giá trị a(i) trong mảng. + Tiếp theo, ta đặt ans= mode(id(l)+1,id(r)1) + Sau đó, với mỗi phần tử a(i) nằm ở phần dư bên phải, ta sẽ nhảy đến phần tử mang giá trị a(i) và xuất hiện thứ j=ians trong mảng, sau đấy ta duyệt trâu: nếu chỉ số mảng của phần tử này vẫn thuộc lr thì ta cập nhật : + j-=1, ans++; + Tương tự với phần dư bên trái nhưng ta lấy j=i+ans và cập nhật j += 1. + sau khi duyệt hết 2 phần dư thì ans sẽ là đáp án của truy vấn. Độ phức tạp của thuật toán sẽ là : 1. Do ta duyệt trâu nên sẽ tốn tối đa 2 × n lần duyệt cho mỗi truy vấn. 2. Thoạt nhìn, thuật toán có thể lên tới O(n) cho mỗi truy vấn. Nhưng từ nhận xét (1) thì số lần duyệt tăng lên chỉ tối đa là 2 × n. Vậy độ phức tạp cho bài toán là O(n × n) Code mẫu : cpp#clude<bitsstdc++.h>usingnamespacestd;#defelllonglong#defefifirst#defescsecond#defeTASKmain#defeall(x)(x).beg(x),(x).end()#defepllpair<ll,ll>constnmax=2e5+6;constsz=450;r<>pos[nmax];b[nmax];/thtxuthincaa[i]trongmng.lla[nmax];c[nmax];llmode[sz+6][sz+6];llBL;n,q;cnt[nmax];f÷[nmax];levoi(ll&a,llb){a=max(a,b);}voreprocess(){for(i=1;iBL;++i){mx=0;memset(cnt,0,sizeofcnt);for(j=min(n-1,isz-1);j0;--j){cnt[a[j]]++;mx=max(mx,cnt[a[j]]);/coutj;mode[f÷[j]][i]=mx;}}memset(cnt,0,sizeofcnt);}query(l,r){l1=f÷[l]+1;r1=f÷[r]-1;ans=0;if(l1>r1){/Trưnghp1for(i=l;ir;++i){cnt[a[i]]++;ans=max(ans,cnt[a[i]]);}for(i=l;ir;++i){cnt[a[i]]=0;}}else{/trưnghp2ans=mode[l1][r1];for(i=r1sz;ir;++i){j=b[i]-ans;whi(j0&&pos[a[i]][j]l){++ans;--j;}}for(i=l;i<(l1-1)sz;++i){j=b[i]+ans;whi(j<pos[a[i]].size()&&pos[a[i]][j]r){++ans;++j;}}}returnans;}voolve(){cnq;for(i=0;i<n;i++){ca[i];b[i]=pos[a[i]].size();/lưutrttcchscacácphntcóchunggiátrpos[a[i]].pushback(i);}BL=nsz+(n%sz0);for(i=0;in;++i){f÷[i]=isz+1;}preprocess();lans=0;whi(q--){l,r;clr;l=(lans+l)%n+1;r=(lans+r)%n+1;--l,--r;if(l>r)swap(l,r);lans=query(l,r);coutlansn;}}ma(){ios::syncwithstdio(false);c.tie(0);cout.tie(0);if(fopen(TASK.inp,r)){eopen(TASK.inp,r,std);eopen(TASK.out,w,stdout);}solve();}