• 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
    ", ans);
    95     }
    96 }
  • 相关阅读:
    夺命雷公狗---Thinkphp----16之首页的完成及全站的完成
    夺命雷公狗---Thinkphp----15之遍历出来的栏目页的完成
    夺命雷公狗---Thinkphp----14之前台的首页完善
    夺命雷公狗-----tp中遇到数据乘积的问题的遇见
    夺命雷公狗---Thinkphp----13之前台的头尾分离和导航分离
    夺命雷公狗---Thinkphp----12之文章的增删改查(图片上传和关联查询)
    夺命雷公狗TP下关联查询
    夺命雷公狗---Thinkphp----11之管理员的增删改查的完善
    夺命雷公狗---Thinkphp----10之后台登录.注销一条龙
    夺命雷公狗---Thinkphp----9之中间层的创建,防止跨目录访问
  • 原文地址:https://www.cnblogs.com/cminus/p/8571228.html
Copyright © 2020-2023  润新知