题链
—— 题意在线求区间众数,若有多个输出权值最小的那个;
离线可采用莫队,在线由于区间众数不满足区间可加性(或许我不知道,不会维护),所以采用分块方式来写;
—— 对于数据范围首先离散化,对长度为 $n$ 的数组分为 $\sqrt(n)$ 块,预处理出第 $i$ 块到第 $j$ 块的区间众数答案;
预处理出数组每一个不同值的位置,$vector$存储;
对于一个询问$[l,r]$,若 $l$ 所在的块和 $r$ 所在的块距离 $<= 1$,则暴力求解 $[l,r]$ 的答案;
否则可以将 $[l,r]$ 划分为 $[l,L)$,$[L,R]$,$(R,r]$ 三个块,其中 $[L,R]$ 是指 $[l,r]$ 之间所有的块;
可以发现ans要么是预处理出的 $[L,R]$ 的答案,要么$ans$是在,$[l,L)$ ,$(R,r]$ 之中,对于这两个区间,遍历每个值,用刚才存位置的 $vector$ 二分查找出现次数;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 #include <bits/stdc++.h> using namespace std;#define LL long long #define ll long long #define ULL unsigned long long #define Pair pair<LL,LL> #define ls rt<<1 #define rs rt<<1|1 #define Pi acos(-1.0) #define eps 1e-6 #define DBINF 1e100 #define mod 998244353 #define MAXN 1e18 #define MS 40009 const int sqMS = sqrt (MS)+5 ;int n,m;int a[MS]; int b[MS],tb;int c[MS]; int size,bknum; int bkl[MS],bkr[MS]; int belong[MS]; vector<int > vc[MS]; int cnt[MS]; int p[sqMS][sqMS]; void a_hash_c () { sort (b+1 ,b+n+1 ); tb = 1 ; for (int i=2 ;i<=n;i++){ if (b[i] != b[i-1 ]) b[++tb] = b[i]; } for (int i=1 ;i<=n;i++){ c[i] = lower_bound (b+1 ,b+tb+1 ,a[i]) - b; } } void init_bk () { size = sqrt (n); bknum = n/size; for (int i=1 ;i<=bknum;i++){ bkl[i] = (i-1 )*size+1 ; bkr[i] = i*size; } if (bkr[bknum] < n){ bknum++; bkl[bknum] = bkr[bknum-1 ]+1 ; bkr[bknum] = n; } for (int i=1 ;i<=bknum;i++){ for (int j=bkl[i];j<=bkr[i];j++){ belong[j] = i; } } } void init_numpos () { for (int i=1 ;i<=n;i++){ vc[c[i]].push_back (i); } } void init_p () { for (int i=1 ;i<=bknum;i++){ int ans = 0 ; int cntans = 0 ; memset (cnt,0 ,sizeof cnt); for (int j=bkl[i];j<=n;j++){ cnt[c[j]]++; if (cntans < cnt[c[j]] || (cntans == cnt[c[j]] && ans > c[j])){ ans = c[j]; cntans = cnt[c[j]]; } p[i][belong[j]] = ans; } } } int main () { ios::sync_with_stdio (false ); cin >> n >> m; for (int i=1 ;i<=n;i++){ cin >> a[i]; b[i] = a[i]; } a_hash_c (); init_bk (); init_numpos (); init_p (); int lastans = 0 ; while (m--){ int l,r; cin >> l >> r; l = (l+lastans-1 )%n+1 ; r = (r+lastans-1 )%n+1 ; if (l > r) swap (l,r); if (belong[r] - belong[l] <= 1 ){ int ans = 0 ; int cntans = 0 ; for (int i=l;i<=r;i++){ int lpos = lower_bound (vc[c[i]].begin (),vc[c[i]].end (),l) - vc[c[i]].begin (); int rpos = upper_bound (vc[c[i]].begin (),vc[c[i]].end (),r) - vc[c[i]].begin (); int cc = rpos - lpos; if (cc > cntans || (cc == cntans && c[i] < ans)){ ans = c[i]; cntans = cc; } } cout << b[ans] << "\n" ; lastans = b[ans]; continue ; } int L = belong[l]+1 ; int R = belong[r]-1 ; int ans = p[L][R]; int lanspos = lower_bound (vc[ans].begin (),vc[ans].end (),l) - vc[ans].begin (); int ranspos = lower_bound (vc[ans].begin (),vc[ans].end (),r) - vc[ans].begin (); int cntans = ranspos - lanspos; for (int i=l;i<=bkl[L]-1 ;i++){ int lpos = lower_bound (vc[c[i]].begin (),vc[c[i]].end (),l) - vc[c[i]].begin (); int rpos = upper_bound (vc[c[i]].begin (),vc[c[i]].end (),r) - vc[c[i]].begin (); int cc = rpos - lpos; if (cc > cntans || (cc == cntans && c[i] < ans)){ ans = c[i]; cntans = cc; } } for (int i=bkr[R]+1 ;i<=r;i++){ int lpos = lower_bound (vc[c[i]].begin (),vc[c[i]].end (),l) - vc[c[i]].begin (); int rpos = upper_bound (vc[c[i]].begin (),vc[c[i]].end (),r) - vc[c[i]].begin (); int cc = rpos - lpos; if (cc > cntans || (cc == cntans && c[i] < ans)){ ans = c[i]; cntans = cc; } } cout << b[ans] << "\n" ; lastans = b[ans]; } return 0 ; }