# BZOJ3744 Gty的妹子序列

n ^ 2 / size * log(n ^ 2 / size) + m * size * log(size)最小。。

  1 /**************************************************************
2     Problem: 3744
3     User: rausen
4     Language: C++
5     Result: Accepted
6     Time:10876 ms
7     Memory:50872 kb
8 ****************************************************************/
9
10 #include <cstdio>
11 #include <cmath>
12 #include <cctype>
13 #include <cstring>
14 #include <algorithm>
15
16 #define lowbit(x) x & -x
17 using namespace std;
18
19 const int N = 50005;
20 const int B = 250;
21 int n, m;
22 int T, block, size;
23 int pos[N], st[B];
24 int BIT[N], vis[N];
25 int ans[B][B];
26 int cnt[B][N];
27 int a[N], b[N];
28
30     int x = 0;
31     char ch = getchar();
32     while (!isdigit(ch))
33         ch = getchar();
34     while (isdigit(ch)) {
35         x = x * 10 + ch - '0';
36         ch = getchar();
37     }
38     return x;
39 }
40
41 inline int find(const int x) {
42     int l = 1, r = n + 1, mid;
43     while (l + 1 < r) {
44         mid = (l + r) >> 1;
45         if (b[mid] <= x) l = mid;
46         else r = mid;
47     }
48     return l;
49 }
50
52     while (x <= n) {
53         if (vis[x] != T) vis[x] = T, BIT[x] = 1;
54         else ++BIT[x];
55         x += lowbit(x);
56     }
57 }
58
59 inline int query(int x) {
60     int res = 0;
61     while(x) {
62         if (vis[x] == T)
63             res += BIT[x];
64         x -= lowbit(x);
65     }
66     return res;
67 }
68
69 int Work(int l, int r) {
70     ++T;
71     if (pos[l] == pos[r]) {
72         int res = 0;
73         for (; r >= l; --r)
74             res += query(a[r] - 1), add(a[r]);
75         return res;
76     }
77     int res, cnt_all, i;
78     res = ans[pos[l] + 1][pos[r] - 1];
79     cnt_all = st[pos[r]] - st[pos[l] + 1];
80     for (i = st[pos[l] + 1] - 1; i >= l; --i) {
81         res += query(a[i] - 1) + cnt[pos[r] - 1][a[i] - 1] - cnt[pos[l]][a[i] - 1];
83     }
84     for (i = st[pos[r]]; i <= r; ++i) {
85         res += cnt_all - query(a[i]) - cnt[pos[r] - 1][a[i]] + cnt[pos[l]][a[i]];
87     }
88     return res;
89 }
90
91 void Block() {
92     int i;
93     size = (int) sqrt(n);
94     for (i = 1; i <= n; ++i)
95         pos[i] = (i - 1) / size + 1;
96     block = pos[n];
97     for (i = 1; i <= block; ++i)
98         st[i] = size * (i - 1) + 1;
99     st[block + 1] = n + 1;
100 }
101
102 void pre_work() {
103     int cnt_now, cnt_all, i, j, k;
104     for (i = 1; i <= block; ++i) {
105         cnt_now = cnt_all = 0, ++T;
106         memcpy(cnt[i], cnt[i - 1], sizeof(cnt[i]));
107         for (j = i; j <= block; ++j)
108             for (k = st[j]; k <= st[j + 1] - 1; ++k) {
109                 cnt_now += cnt_all - query(a[k]);
110                 ans[i][j] = cnt_now;
112                 ++cnt_all, ++cnt[j][a[k]];
113             }
114     }
115     for (i = 1; i <= block; ++i)
116         for (j = 2; j <= n; ++j)
117             cnt[i][j] += cnt[i][j - 1];
118 }
119
120 int main() {
121     int i;
123     for (i = 1; i <= n; ++i)
124         a[i] = b[i] = read();
126     sort(b + 1, b + n + 1);
127     for (i = 1; i <= n; ++i)
128         a[i] = find(a[i]);
129     Block();
130     pre_work();
131     int L, R, ans = 0;
132     while (m--) {
137 }