# BZOJ 3809 Gty的二逼妹子序列

Description:

Solution:

nsqrt(n)logn的很容易想到，但是会超。

Code:

 1 #include <cstdio>
2 #include <cstdlib>
3 #include <cstring>
4 #include <string>
5 #include <algorithm>
6 #include <cmath>
7
8 using namespace std;
9
10 #define REP(i, a, b) for (int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
11 const int maxn = 1e5+10, maxm = 1e6+10;
12 int n, m, a[maxn];
13 int bel[maxn], l[maxn], r[maxn], s_block;
14 struct Query
15 {
16     int l, r, a, b, id;
17     void read(int i) { scanf("%d %d %d %d", &l, &r, &a, &b), id = i; }
18     bool operator < (const Query &AI) const { return bel[l] == bel[AI.l] ? r < AI.r : l < AI.l; }
19 }q[maxm];
20 int s[1100], c[maxn], ans[maxm];
21
22 int calc(int x, int y)
23 {
24     int L = bel[x], R = bel[y], ret = 0;
25     if (L == R)
26     {
27         REP(i, x, y) if (c[i]) ret ++;
28     }
29     else
30     {
31         REP(i, L+1, R-1) ret += s[i];
32         REP(i, x, r[L]) if (c[i]) ret ++;
33         REP(i, l[R], y) if (c[i]) ret ++;
34     }
35     return ret;
36 }
37
38 void add(int x) { if (++c[x] == 1) s[bel[x]] ++; }
39
40 void del(int x) { if (--c[x] == 0) s[bel[x]] --; }
41
42 void solve()
43 {
44     int now_l = 1, now_r = 0;
45     REP(i, 1, m)
46     {
47         for (; now_r < q[i].r; add(a[++now_r]));
48         for (; now_l > q[i].l; add(a[--now_l]));
49         for (; now_r > q[i].r; del(a[now_r--]));
50         for (; now_l < q[i].l; del(a[now_l++]));
51         ans[q[i].id] = calc(q[i].a, q[i].b);
52     }
53 }
54
55 int main()
56 {
57     scanf("%d %d", &n, &m);
58     REP(i, 1, n) scanf("%d", &a[i]);
59     int block = int(sqrt(n));
60     REP(i, 1, n)
61     {
62         bel[i] = i/block+1, r[bel[i]] = i;
63         if (i == 1 || bel[i] != bel[i-1]) l[bel[i]] = i;
64     }
65     s_block = n/block+1;
67     sort(q+1, q+m+1);
68     solve();
69     REP(i, 1, m) printf("%d\n", ans[i]);
70     return 0;
71 }
View Code

//if为了省行，少了括号，调了很久

Nothing is impossible！
posted @ 2017-04-10 22:04  Splay  阅读(151)  评论(0编辑  收藏  举报