P4168 [Violet] dandelion
Question Background
Dear brother:
Are you doing well in that city?
I am very happy at home recently. My grandmother told me the story of the bad guy called "Despair" last night! It breaks down people's houses and lands, and many other children are killed by it. I think the bad guy who summoned such a terrible monster is also very bad. But grandma said that he did this when he was uncomfortable ......
Recently, a large piece of dandelion has grown in the village. Once the wind blows, these dandelion will be able to flow far away. I think it would be nice to let my brother see it if they could move into that city!
Come back soon, brother!
Love your sister \ (violet \)
\ (Azure \) smiled after reading this letter.
"Dandelion ......"
Description
Many dandelion grows along the small road in the country, and our problems are related to these dandelion.
For the sake of simplification, we regard all dandelion as a sequence of \ (n \) \ (A_1, A_2 \ cdots a_n) \), where \ (a_ I \) is a positive integer that represents the type Number of the Dandelion.
Each time you ask for an interval \ ([L, R] \), you need to answer which of the most frequently occurring dandelion in the interval. If there are several dandelion that appear the same number of times, the minimum number of the output type.
Note that your algorithm must be online
Input/output format:
The two integers \ (n, m \) in the first line indicate that there are \ (n \) dandelion strains and \ (M \) requests.
The next line \ (n \) is a space-separated integer \ (a_ I \), indicating the dandelion type
Next, there are two integers \ (l_0, R_0 \) in each row in the \ (M \) line. The result of the last query is \ (x \) (if this is the first query, then \ (x = 0 \)).
Order \ (L = (l_0 + x-1) \ bmod n + 1, R = (R_0 + x-1) \ bmod n + 1 \), if \ (L> r \), then \ (L, r \) is switched \).
The final query interval is [L, R].
Output Format:
Output \ (M \) rows. Each row has an integer representing the result of each query.
Input and Output sample input sample #1:
6 31 2 3 2 1 21 53 61 5
Output sample #1:
121
Description
For \ (20 \ % \) data, ensure \ (1 \ Le n, m \ le 3000 \).
For \ (100 \ % \) data, ensure \ (1 \ Le n \ le 40000,1 \ le m \ le 50000,1 \ le a_ I \ le 10 ^ 9 \).
Ideas
\ (600 \ AC \)! Organize blogs. -- Uranus
I picked up the tumor from the chunks and made this question at the recommendation of \ (alecli.
We divide the sequence into blocks. After discretization, we record the number of occurrences of each number in each block. The largest number of occurrences is the mode. Here, I use array \ (s [I] [J] [k] \) to represent the numbers from the \ (I \) block to the \ (J \) block \ (k \). Then we will count the number of modes in the interval, and use \ (MD [I] [J] \) to record the mode size, \ (TMS [I] [J] \) to record the number of occurrences of the mode.
The Preprocessing ends here. Next, consider the query operation. For the interval of each query, it must be composed of a large block, the number on the left of the large block, and the number on the right. Obviously, the final mode of this range is the number of large blocks, or the number on the left side of a large block, or the number on the right side of a large block.
Then we will directly use the three arrays of the large blocks that we have previously calculated. On this basis, we will add the two small blocks to the same method during preprocessing. After counting the answer, we will remove the small blocks, you can easily query and maintain the pre-processing array.
Since it is a block, there must be a lot of details. Specifically, there are several:
- Consider discretization and constant optimization.
- If the query range does not contain large blocks, the two blocks are directly processed.
- \ (Alecli \) indicates that the block size will affect the time complexity, and tells me that the block size is \ (N ^ \ frac {2} {3 }\), although I don't know why.
As long as you are patiently debugging, you will eventually be able to \ (AC \). Good luck!
AC code
#include<bits/stdc++.h>using namespace std;const int MAXN=4e4+5,MAXM=45;int n,m,len,ans,cnt,a[MAXN],b[MAXN],c[MAXN];int sz,num,l[MAXM],r[MAXM],belong[MAXN],s[MAXM][MAXM][MAXN],md[MAXM][MAXM],tms[MAXM][MAXM];int read(){ int re=0;char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)) re=(re<<3)+(re<<1)+ch-'0',ch=getchar(); return re;}void print(int x,bool first){ if(!x) { if(first) putchar('0'); return ; } print(x/10,false); putchar('0'+x%10);}void prework(){ num=pow(double(n),1.0/3.0),sz=n/num; for(int i=1;i<=num;i++) l[i]=r[i-1]+1,r[i]=sz*i; if(r[num]<n) num++,l[num]=r[num-1]+1,r[num]=n; for(int i=1;i<=num;i++) for(int j=l[i];j<=r[i];j++) belong[j]=i; sort(b+1,b+n+1); len=unique(b+1,b+n+1)-b-1; for(int i=1;i<=n;i++) c[i]=lower_bound(b+1,b+len+1,a[i])-b; for(int i=1;i<=num;i++) for(int j=i;j<=num;j++) { for(int k=l[i];k<=r[j];k++) s[i][j][c[k]]++; for(int k=1;k<=len;k++) if(tms[i][j]<s[i][j][k]||(tms[i][j]==s[i][j][k]&&k<md[i][j])) md[i][j]=k,tms[i][j]=s[i][j][k]; }}void ask(int ll,int rr){ if(ll>rr) swap(ll,rr); int lbe=belong[ll],rbe=belong[rr],L,R;ans=cnt=0; if(rbe-lbe<=2) L=R=0; else L=lbe+1,R=rbe-1; if(L==R) { for(int i=ll;i<=rr;i++) { s[L][R][c[i]]++; if(cnt<s[L][R][c[i]]||(cnt==s[L][R][c[i]]&&ans>c[i])) cnt=s[L][R][c[i]],ans=c[i]; } for(int i=ll;i<=rr;i++) s[L][R][c[i]]--; } else { ans=md[L][R],cnt=tms[L][R]; for(int i=ll;i<=r[lbe];i++) { s[L][R][c[i]]++; if(cnt<s[L][R][c[i]]||(cnt==s[L][R][c[i]]&&ans>c[i])) cnt=s[L][R][c[i]],ans=c[i]; } for(int i=l[rbe];i<=rr;i++) { s[L][R][c[i]]++; if(cnt<s[L][R][c[i]]||(cnt==s[L][R][c[i]]&&ans>c[i])) cnt=s[L][R][c[i]],ans=c[i]; } for(int i=ll;i<=r[lbe];i++) s[L][R][c[i]]--; for(int i=l[rbe];i<=rr;i++) s[L][R][c[i]]--; } ans=b[ans];}int main(){ n=read(),m=read(); for(int i=1;i<=n;i++) a[i]=b[i]=read(); prework(); while(m--) { int x=(read()+ans-1)%n+1,y=(read()+ans-1)%n+1; ask(x,y); print(ans,true);putchar('\n'); } return 0;}
Luogu p4168 [Violet] dandelion