• 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
  • 相关阅读:
    特征选择常用算法综述
    C++中的extern "C"
    OpenGL管道概括
    使用CGAL查找输入三角网格模型独立模型个数
    图形学领域的关键算法及源码链接
    STL学习笔记
    CGAL+QT4.84+Boost1.53 错误[Parse error at "BOOST_JOIN"]
    Template函数
    在windows环境下安装配置CGAL
    关于C++中的堆、栈
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8400267.html
Copyright © 2020-2023  润新知