BZOJ2724: [Violet 6]蒲公英
2724: [Violet 6]蒲公英
Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 2596 Solved: 903
[Submit][Status][Discuss]
Description
Input
修正一下
l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1
Output
Sample Input
6 3
1 2 3 2 1 2
1 5
3 6
1 5
1 2 3 2 1 2
1 5
3 6
1 5
Sample Output
1
2
1
2
1
HINT
修正下:
n <= 40000, m <= 50000
Source
【题解】
开始看陈立杰巨神的结题报告。。
TLE。。。
然后看了看hzwer的题解。。秒啊。。
分块预处理第i块到第j块的众数是谁以及众数个数,可以用vector[i]表示数值为i的下标是多少,从小往大单调着挂,这样就可以二分得出区间内的某个数的个数
在预处理第i块到第j块时,第i + 1到j - 1块已经求出,继承过来;还有一种情况是众数在第i块或第j块上,枚举,二分看个数
询问同理
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <queue> 7 #include <vector> 8 #include <map> 9 #include <string> 10 #include <cmath> 11 #define min(a, b) ((a) < (b) ? (a) : (b)) 12 #define max(a, b) ((a) > (b) ? (a) : (b)) 13 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a)) 14 template<class T> 15 inline void swap(T &a, T &b) 16 { 17 T tmp = a;a = b;b = tmp; 18 } 19 inline void read(int &x) 20 { 21 x = 0;char ch = getchar(), c = ch; 22 while(ch < '0' || ch > '9') c = ch, ch = getchar(); 23 while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar(); 24 if(c == '-') x = -x; 25 } 26 const int INF = 0x3f3f3f3f; 27 const int MAXN = 100000 + 10; 28 std::vector<int> vec[MAXN]; 29 int n,m,num[MAXN],block[MAXN],size,group,l[MAXN],r[MAXN],p[1000][1000],pp[1000][1000],c[MAXN],cnt[MAXN],ma,recnt[MAXN]; 30 int cmp(int a, int b) 31 { 32 return num[a] < num[b]; 33 } 34 //查找等于x的数有多少 35 int erfen(int x, int ll, int rr) 36 { 37 return std::upper_bound(block + ll, block + rr + 1, x) - std::lower_bound(block + ll, block + rr + 1, x); 38 } 39 void query(int ll, int rr, int &shu) 40 { 41 int ans = 0, bl = (ll - 1) / size + 1, br = (rr - 1) / size + 1; 42 if(bl + 2 <= br) ans = p[bl + 1][br - 1], shu = pp[bl + 1][br - 1]; 43 for(int i = ll;i <= r[bl];++ i) 44 { 45 int tmp = upper_bound(vec[num[i]].begin(), vec[num[i]].end(), rr) - lower_bound(vec[num[i]].begin(), vec[num[i]].end(), i); 46 if(tmp > ans) ans = tmp, shu = num[i]; 47 else if(tmp == ans && shu > num[i]) shu = num[i]; 48 } 49 for(int i = rr;i >= l[br];-- i) 50 { 51 int tmp = upper_bound(vec[num[i]].begin(), vec[num[i]].end(), i) - lower_bound(vec[num[i]].begin(), vec[num[i]].end(), ll); 52 if(tmp > ans) ans = tmp, shu = num[i]; 53 else if(tmp == ans && shu > num[i]) shu = num[i]; 54 } 55 } 56 void make_cnt() 57 { 58 for(int i = 1;i <= n;++ i) vec[num[i]].push_back(i); 59 for(int i = group;i >= 1;-- i) 60 for(int j = i;j <= group;++ j) 61 { 62 pp[i][j] = INF; 63 if(i + 2 <= j) p[i][j] = p[i + 1][j - 1], pp[i][j] = pp[i + 1][j - 1]; 64 for(int k = l[i];k <= r[i];++ k) 65 { 66 int tmp = upper_bound(vec[num[k]].begin(), vec[num[k]].end(), r[j]) - lower_bound(vec[num[k]].begin(), vec[num[k]].end(), k); 67 if(tmp > p[i][j]) p[i][j] = tmp, pp[i][j] = num[k]; 68 else if(tmp == p[i][j] && num[k] < pp[i][j]) pp[i][j] = num[k]; 69 } 70 for(int k = l[j];k <= r[j];++ k) 71 { 72 int tmp = upper_bound(vec[num[k]].begin(), vec[num[k]].end(), k) - lower_bound(vec[num[k]].begin(), vec[num[k]].end(), l[i]); 73 if(tmp > p[i][j]) p[i][j] = tmp, pp[i][j] = num[k]; 74 else if(tmp == p[i][j] && num[k] < pp[i][j]) pp[i][j] = num[k]; 75 } 76 } 77 } 78 int main() 79 { 80 read(n), read(m); 81 for(int i = 1;i <= n;++ i) read(num[i]),cnt[i] = i; 82 std::sort(cnt + 1, cnt + 1 + n, cmp); 83 int pre = 0; 84 for(int i = 1;i <= n;++ i) 85 { 86 if(pre != num[cnt[i]]) ++ ma; 87 pre = recnt[ma] = num[cnt[i]]; 88 num[cnt[i]] = block[cnt[i]] = ma; 89 } 90 size = sqrt(n); 91 for(int i = 1;i <= n;i += size) 92 l[++ group] = i, r[group] = min(i + size - 1, n), std::sort(block + l[group], block + r[group] + 1); 93 make_cnt(); 94 pre = 0; 95 for(int i = 1;i <= m;++ i) 96 { 97 int tmp1,tmp2,tmp3; 98 read(tmp1), read(tmp2); 99 tmp1 = (tmp1 + pre - 1) % n + 1, tmp2 = (tmp2 + pre - 1) % n + 1; 100 if(tmp1 > tmp2) swap(tmp1, tmp2); 101 query(tmp1, tmp2, tmp3); 102 pre = recnt[tmp3]; 103 printf("%d\n", recnt[tmp3]); 104 } 105 return 0; 106 }