洛谷P3709 大爷的字符串

题意:多次求区间众数的出现次数。

解:

这题居然可以莫队......

首先开个桶。然后还要开个数组,cnt[i]表示出现i次的数有多少个。

然后就可以O(1)修改了。

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cmath>
  4 
  5 inline void read(int &x) {
  6     x = 0;
  7     char c = getchar();
  8     while(c < '0' || c > '9') {
  9         c = getchar();
 10     }
 11     while(c >= '0' && c <= '9') {
 12         x = (x << 3) + (x << 1) + c - 48;
 13         c = getchar();
 14     }
 15     return;
 16 }
 17 
 18 const int N = 200010;
 19 
 20 int fr[N], a[N], bin[N], cnt[N], ans, X[N];
 21 
 22 struct ASK {
 23     int l, r, t, ans;
 24     inline bool operator <(const ASK &w) const {
 25         if(fr[l] != fr[w.l]) {
 26             return fr[l] < fr[w.l];
 27         }
 28         return r < w.r;
 29     }
 30 }ask[N];
 31 
 32 inline bool cmp(const ASK &A, const ASK &B) {
 33     return A.t < B.t;
 34 }
 35 
 36 inline void add(int p) {
 37     cnt[bin[a[p]]]--;
 38     bin[a[p]]++;
 39     cnt[bin[a[p]]]++;
 40     if(bin[a[p]] > ans) {
 41         ans = bin[a[p]];
 42     }
 43     return;
 44 }
 45 
 46 inline void del(int p) {
 47     cnt[bin[a[p]]]--;
 48     bin[a[p]]--;
 49     cnt[bin[a[p]]]++;
 50     if(!cnt[bin[a[p]] + 1] && ans == bin[a[p]] + 1) {
 51         ans--;
 52     }
 53     return;
 54 }
 55 
 56 int main() {
 57     int n, m;
 58     read(n);
 59     read(m);
 60     int T = sqrt(n);
 61     for(int i = 1; i <= n; i++) {
 62         read(a[i]);
 63         X[i] = a[i];
 64         fr[i] = (i - 1) / T + 1;
 65     }
 66     for(int i = 1; i <= n; i++) {
 67         read(ask[i].l);
 68         read(ask[i].r);
 69         ask[i].t = i;
 70     }
 71     std::sort(X + 1, X + n + 1);
 72     std::sort(ask + 1, ask + m + 1);
 73     int temp = std::unique(X + 1, X + n + 1) - X - 1;
 74     for(int i = 1; i <= n; i++) {
 75         a[i] = std::lower_bound(X + 1, X + temp + 1, a[i]) - X;
 76     }
 77 
 78     int l = 1, r = 1;
 79     ans = 1;
 80     bin[a[1]]++;
 81     cnt[1] = 1;
 82     for(int i = 1; i <= m; i++) {
 83         while(l > ask[i].l) {
 84             add(--l);
 85         }
 86         while(r < ask[i].r) {
 87             add(++r);
 88         }
 89         while(l < ask[i].l) {
 90             del(l++);
 91         }
 92         while(r > ask[i].r) {
 93             del(r--);
 94         }
 95         ask[i].ans = ans;
 96     }
 97 
 98     std::sort(ask + 1, ask + m + 1, cmp);
 99     for(int i = 1; i <= m; i++) {
100         printf("%d\n", -ask[i].ans);
101     }
102     return 0;
103 }
AC代码

 

posted @ 2019-01-02 18:35  huyufeifei  阅读(...)  评论(...编辑  收藏