bzoj3744: Gty的妹子序列 (BIT && 分块)

强制在线的区间询问逆序对数

如果不是强制在线

就是可以用莫队乱搞啦

强制在线的话

用f[i][j]记录第i块到第j个点之间的逆序对数

用s[i][j]记录前i块中小于等于j的数字个数

离散化一下

BIT用来处理需要暴力的地方即可

下面是代码

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cmath>
 4 #include <cstring>
 5 using namespace std;
 6 #define isdigit(x) (x <= ‘9‘ && x >= ‘0‘)
 7 #define lowbit(x) (x & (-x))
 8 const int N = 5e4 + 5;
 9 const int M = 300;
10
11 struct s {
12     int u, v;
13     inline bool operator < (const s &o) const {
14         return u < o.u;
15     }
16 } a[N];
17
18 inline void read(int &ans) {
19     ans = 0;
20     static char buf = getchar();
21     for (; !isdigit(buf); buf = getchar());
22     for (; isdigit(buf); buf = getchar())
23         ans = ans * 10 + buf - ‘0‘;
24 }
25
26 int n, cnt, maxn, sz;
27 int s[M][N], f[M][N], c[N], d[N], b[N];
28
29 inline void add(int x, int a) {
30     while (x <= maxn) {
31         c[x] += a;
32         x += lowbit(x);
33     }
34 }
35
36 inline int query(int x) {
37     int ans = 0;
38     while (x > 0) {
39         ans += c[x];
40         x -= lowbit(x);
41     }
42     return ans;
43 }
44
45 inline void work(int x) {
46     int h = (x - 1) * sz + 1;
47     int t = x * sz;
48     for (int i = h; i <= n; i++)
49         add(d[i], 1), f[x][i] = f[x][i - 1] + i - h + 1 - query(d[i]);
50     memset(c, 0, sizeof(c));
51     for (int i = h; i <= t; i++)    s[x][d[i]]++;
52     for (int i = 1; i <= maxn; i++)    s[x][i] += s[x][i - 1];
53     for (int i = 1; i <= maxn; i++)    s[x][i] += s[x - 1][i];
54 }
55
56 int main() {
57     read(n);
58     sz = sqrt(n);
59     for (int i = 1; i <= n; i++) {
60         read(a[i].u); a[i].v = i;
61         b[i] = (i - 1) / sz + 1;
62     }
63     cnt = b[n];
64     sort(a + 1, a + n + 1);
65     int last = 1; d[a[1].v] = 1;
66     for (int i = 2; i <= n; i++) {
67         if (a[i].u == a[i - 1].u)    d[a[i].v] = last;
68         else    d[a[i].v] = ++last;
69     }
70     maxn = last;
71     for (int i = 1; i <= cnt; i++)
72         work(i);
73     int m; read(m);
74     int ans = 0;
75     while (m--) {
76         int l, r;
77         read(l); read(r);
78         l = l ^ ans; r = r ^ ans;
79         ans = 0;
80         if (l > r)    swap(l, r);
81         if (b[l] == b[r]) {
82             for (int i = l; i <= r; i++)
83                 add(d[i], 1), ans += i - l + 1 - query(d[i]);
84             for (int i = l; i <= r; i++)    add(d[i], -1);
85         }
86         else {
87             ans = f[b[l] + 1][r];
88             for (int i = (b[r] - 1) * sz + 1; i <= r; i++)    add(d[i], 1);
89             for (int i = b[l] * sz; i >= l; i--)
90                 add(d[i], 1), ans += query(d[i] - 1) + s[b[r] - 1][d[i] - 1] - s[b[l]][d[i] - 1];
91             for (int i = (b[r] - 1) * sz + 1; i <= r; i++)    add(d[i], -1);
92             for (int i = l; i <= b[l] * sz; i++)    add(d[i], -1);
93         }
94         printf("%d\n", ans);
95     }
96 }

原文地址:https://www.cnblogs.com/cminus/p/8571228.html

时间: 2024-10-26 05:47:09

bzoj3744: Gty的妹子序列 (BIT && 分块)的相关文章

【分块】【树状数组】bzoj3744 Gty的妹子序列

离散化,分块. 预处理出:ans[i][j] 第i块到第j块的逆序对数. f[i][j] 第1~i块中大于j的数的个数. g[i][j] 第1~j块中小于j的数的个数. 每次询问时对于整块部分可以O(1)获得. 对于零散部分呢? >在一列数的后面添加一个数,逆序对数会增加 数列中比它大的数的个数. >在一列数的前面添加一个数,逆序对数会增加 数列中比它小的数的个数. 所以统计以上信息的时候,对于整块的部分,我们可以借由预处理的东西差分来O(1)地获得答案,零散的部分就是树状数组咯. 空间复杂度

bzoj3744 Gty的妹子序列

我是萌萌的传送门 感觉这题还是不错的--虽然其实算是比较水的题= = 首先分块,令f[i][j]表示第i块到第j块的逆序对数,询问的时候直接计算不完整块与完整块以及不完整块之间的逆序对. 不完整块之间的逆序对直接树状数组暴力求,至于不完整块和完整块的逆序对,我是令s[i]表示前i块的权值前缀和,这样单次查询O(1),可以减小一点常数,代价是空间稍微费了点-- 预处理O(nsqrt(n)logn),单次查询O(sqrt(n)logn),空间O(nsqrt(n)),好吧我懒得算如何调节块大小来降低复

bzoj 3744: Gty的妹子序列 主席树+分块

3744: Gty的妹子序列 Time Limit: 15 Sec  Memory Limit: 128 MBSubmit: 101  Solved: 34[Submit][Status] Description 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成了一个序列,每个妹子有一个美丽度. Bakser神犇与他打算研究一下这个妹子序列,于是Bakse

BZOJ 3744: Gty的妹子序列

3744: Gty的妹子序列 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1335  Solved: 379[Submit][Status][Discuss] Description 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成了一个序列,每个妹子有一个美丽度. Bakser神犇与他打算研究一下这个妹

【bzoj3744】Gty的妹子序列 分块+树状数组+主席树

题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成了一个序列,每个妹子有一个美丽度. Bakser神犇与他打算研究一下这个妹子序列,于是Bakser神犇问道:"你知道区间 [l,r]中妹子们美丽度的逆序对数吗?" 蒟蒻Autumn只会离线乱搞啊……但是Bakser神犇说道:"强制在线." 请你帮助一下Autumn吧.

BZOJ 3744 Gty的妹子序列 分块+fenwick

题目大意:强制在线区间无修改逆序对. 思路:看到数据范围发现分块是很显然的.预处理了很多东西,比如说每个块里面的逆序对个数,还有f[i][j]表示从第i块到第j块的逆序对个数.如果仅仅处理到这里的话,后面是不太好处理的.我们还需要一个东西,是每个点对每个块的逆序对个数,并取前缀合优化.否则的话就得用主席树来乱搞,那常数 反正总时间复杂度大概是O(n*sqrt(n)*logn)  强行不到O(n^2) 剩下就是小事了, 比如离散话啥的.. CODE: #include <cmath> #incl

【bzoj3744】GTY的妹子序列

大力分块+树状数组+主席树-- #include<bits/stdc++.h> #define N 50005 #define pa pair<int,int> #define fi first #define sc second using namespace std; int n,m,cnt,tot,size,t; int a[N],c[N],num[N],rt[N]; int sum[250][N]; inline int lowbit(int x){return (x&am

bzoj 3744 Gty的妹子序列 区间逆序对数(在线) 分块

题目链接 题意 给定\(n\)个数,\(q\)个询问,每次询问\([l,r]\)区间内的逆序对数. 强制在线. 思路 参考:http://www.cnblogs.com/candy99/p/6579556.html 离线的话就如上一题bzoj 3289 Mato的文件管理,可以直接用 莫队 搞,在线的话怎么办呢? 分块大法好. 1 预处理出两个信息: \(f[i][j]\):从 第\(i\)块开始位置 到 位置\(j\) 这段区间的逆序对数 \(s[i][j]\):前\(i\)块中\(\leq

BZOJ 3744: Gty的妹子序列 [分块]

传送门 题意:询问区间内逆序对数 感觉这种题都成套路题了 两个预处理$f[i][j]$块i到j的逆序对数,$s[i][j]$前i块$\le j$的有多少个 f我直接处理成到元素j,方便一点 用个树状数组就行了 预处理和查询都带$log$所以还是开根号n比较科学吧 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath>