链接:https://ac.nowcoder.com/acm/contest/1034/A
来源:牛客网

题目描述

在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关。
为了简化起见,我们把所有的蒲公英看成一个长度为 n 的序列a1,a2,…,ana_1,a_2,\dots,a_na1,a2,,an,其中aia_iai为一个正整数,表示第 i 棵蒲公英的种类编号。
而每次询问一个区间 [l,r] ,你需要回答区间里出现次数最多的是哪种蒲公英,如果有若干种蒲公英出现次数相同,则输出种类编号最小的那个。

输入描述:

第一行两个整数n,m,表示有 n 株蒲公英,m 次询问。
接下来一行 n 个空格隔开的整数aia_iai,表示蒲公英的种类。
再接下来 m 行每行两个整数l0l_0l0,r0r_0r0,我们令上次询问的结果为 x(如果这是第一次询问,则 x=0)。
l=(l0+x−1) mod n+1,r=(r0+x−1) mod n+1l=(l_0+x-1) \bmod n+1,r=(r_0+x-1) \bmod n+1l=(l0+x1)modn+1,r=(r0+x1)modn+1,如果l>r,则交换l,r。
最终的询问区间为[l,r]。

输出描述:

输出 m 行。
每行一个整数,表示每次询问的结果。

输入

6 3
1 2 3 2 1 2
1 5
3 6
1 5

输出

1
2
1

备注:

1≤n≤40000,1\leq n\leq 40000,1n40000,
1≤m≤50000,1\leq m\leq 50000,1m50000,
1≤ai≤1091\leq a_i\leq 10^91ai109

开始准备用线段树写,写完发现写错了,就上网搜分块写法,觉得很麻烦,但是很有用、、、

sum[i][j]:1-i块内,数值j的数量
p[i][j]:i->j块中众数是哪一个
pos[i]:下标为i的数值归为哪一个块
L[i],R[i]:第i块的起始点以及终止点(认为不需要,只是当时参考的别人代码出现,可以用i*(len-1)+1,i*len代替)

1)需要注意的就是对于区间众数的求解代码。并不是用tong[]扫一遍然后之间遍历数组tong[],找最大值,
而是边统计边比较,tong[arr[i]]++;if(………………)…………;
2)在pos[r]-pos[r]>=2时,先取出整区间的众数,然后边统计,边比较,与1)中做法一样

AC代码
  1 #include <map>
  2 #include <cstdio>
  3 #include <cmath>
  4 #include <cstring>
  5 #include <algorithm>
  6 #define Inf 0x3f3f3f3f
  7 using namespace std;
  8 
  9 map<int,int>ys;
 10 const int N = 40005,M=205;
 11 int n,m,cnt;
 12 int arr[N],tep[N],sum[M][N],p[M][M],pos[N],L[M],R[M],tong[N];
 13 
 14 void Init(void){
 15     int len = sqrt(1.0 * n);
 16 
 17     int num;
 18     for(int i=1;i*len<=n;i++){
 19         L[i]=(i-1)*len+1;
 20         R[i]=i*len;
 21         for(int j=L[i];j<=R[i];j++){
 22             sum[i][arr[j]]++;
 23             pos[j]=i;
 24         }
 25         num=i;
 26     }
 27     num++;
 28     L[num]=len*(num-1)+1,R[num]=n;
 29     for(int i=L[num];i<=n;i++){
 30         pos[i]=num;
 31         sum[num][arr[i]]++;
 32     }
 33 
 34     for(int i=1;i<=num;i++)
 35         for(int j=1;j<=cnt;j++)
 36             sum[i][j]+=sum[i-1][j];
 37 
 38     int col,tot,kth;
 39     for(int i=1;i<=num;i++){
 40             tot=0,col=Inf;
 41             for(int j=L[i];j<=n;j++){
 42                 kth=pos[j];
 43                 tong[arr[j]]++;
 44                 if(tong[arr[j]]>tot || (tong[arr[j]]==tot && col > arr[j]))
 45                     tot=tong[arr[j]],col=arr[j];
 46                 p[i][kth]=col;
 47             }
 48             for(int j=L[i];j<=n;j++)
 49                 tong[arr[j]]=0;
 50     }
 51 }
 52 int query(int l,int r){
 53     memset(tong,0,sizeof(tong));
 54 
 55     int answer,tot;
 56     if(pos[r]-pos[l]<=1){
 57         answer=Inf,tot=0;
 58         for(int i=l;i<=r;i++){
 59             tong[arr[i]]++;
 60             if(tong[arr[i]]>tot || (tong[arr[i]]==tot && answer>arr[i]))
 61                 tot=tong[arr[i]],answer=arr[i];
 62         }
 63         return answer;
 64     }
 65 
 66     int p1=pos[l],p2=pos[r];
 67     answer=p[p1+1][p2-1];
 68     tot=sum[p2-1][answer]-sum[p1][answer];
 69 
 70     int x=l,y=R[p1];//error
 71     for(int i=x;i<=y;i++){
 72         tong[arr[i]]++;
 73         if(tong[arr[i]]+sum[p2-1][arr[i]]-sum[p1][arr[i]]>tot ||(tong[arr[i]]+sum[p2-1][arr[i]]-sum[p1][arr[i]]==tot && answer>arr[i]))
 74             answer=arr[i],tot=tong[arr[i]]+sum[p2-1][arr[i]]-sum[p1][arr[i]];
 75     }
 76 
 77     x=L[p2],y=r;
 78     for(int i=x;i<=y;i++){
 79         tong[arr[i]]++;
 80         if(tong[arr[i]]+sum[p2-1][arr[i]]-sum[p1][arr[i]]>tot ||(tong[arr[i]]+sum[p2-1][arr[i]]-sum[p1][arr[i]]==tot && answer>arr[i]))
 81             answer=arr[i],tot=tong[arr[i]]+sum[p2-1][arr[i]]-sum[p1][arr[i]];
 82     }
 83     return answer;
 84 }
 85 
 86 int  main(void)
 87 {
 88     scanf("%d%d",&n,&m);
 89     for(int i=1;i<=n;i++){
 90         scanf("%d",&arr[i]);
 91         tep[i]=arr[i];
 92     }
 93 
 94     sort(tep+1,tep+1+n);
 95     cnt = unique(tep+1,tep+1+n)-tep-1;
 96     int d;
 97     for(int i=1;i<=n;i++){
 98         d=arr[i];
 99         arr[i]=lower_bound(tep+1,tep+1+cnt,arr[i])-tep;
100         ys[arr[i]]=d;
101     }
102 
103     Init();
104 
105     int l,r,x=0;
106     for(int i=1;i<=m;i++){
107         scanf("%d%d",&l,&r);
108         l=(l+x-1)%n+1;
109         r=(r+x-1)%n+1;
110         if(l>r)
111             swap(l,r);
112         x=ys[query(l,r)];
113         printf("%d\n",x);
114     }
115 
116     return 0;
117 }