BZOJ2724: [Violet 6]蒲公英

2724: [Violet 6]蒲公英

Time Limit: 40 Sec  Memory Limit: 512 MB
Submit: 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

Sample Output

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
", recnt[tmp3]);
104     }
105     return 0;
106 }
BZOJ2724
原文地址:https://www.cnblogs.com/huibixiaoxing/p/8400267.html