Description

题库链接

对于序列 \(A\) ,它的逆序对数定义为满足 \(i<j\) ,且 \(A_i>A_j\) 的数对 \((i,j)\) 的个数。给 \(1\) 到 \(n\) 的一个排列,按照某种顺序依次删除 \(m\) 个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。

Solution

好久以前的坑了...

解法一

考虑树套树。

删去一个数,减少的逆序对个数是当前位置之前比当前数大的个数以及在这个数的位置之后比当前数小的个数。

如果不支持修改显然是可以用主席树来维护的。

由于要支持修改,我们考虑用树状数组套线段树,树状数组维护序列下标。线段树维护数的个数。那么时间和空间复杂度都是 \(O(n\cdot log^2_2 n)\) 的。

解法二

考虑 \(cdq\) 。

首先删数很不好操作,我们考虑从后往前操作,让删数变成添数。

我们可以先按时间排序。添加时间早的数才会对添加时间晚的有贡献。对于 \(cdq\) 的每一次操作就是统计添数时间早于某个数的当前位置之前比当前数大的个数以及在这个数的位置之后比当前数小的个数。

Code

解法一

//It is made by Awson on 2018.2.24
#include <bits/stdc++.h>
#define LL long long
#define dob complex<double>
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('\n'))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = 100000;
void read(int &x) {
char ch; bool flag = 0;
for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
x *= 1-2*flag;
}
void print(LL x) {if (x > 9) print(x/10); putchar(x%10+48); }
void write(LL x) {if (x < 0) putchar('-'); print(Abs(x)); } int n, m, a, id[N+5]; LL ans;
struct Segment_tree {
int root[N+5], ch[N*100][2], key[N*100+5], pos;
int cpynode(int x) {++pos; ch[pos][0] = ch[x][0], ch[pos][1] = ch[x][1], key[pos] = key[x]; return pos; }
void insert(int &o, int l, int r, int loc, int val) {
if (o == 0) o = cpynode(o); key[o] += val;
if (l == r) return; int mid = (l+r)>>1;
if (loc <= mid) insert(ch[o][0], l, mid, loc, val); else insert(ch[o][1], mid+1, r, loc, val);
}
int query(int o, int l, int r, int a, int b) {
if ((a <= l && r <= b) || o == 0) return key[o];
int mid = (l+r)>>1;
int c1 = 0, c2 = 0;
if (a <= mid) c1 = query(ch[o][0], l, mid, a, b);
if (b > mid) c2 = query(ch[o][1], mid+1, r, a, b);
return c1+c2;
}
}ST;
struct bittree {
void add(int o, int val, int key) {for (; o <= n; o += lowbit(o)) ST.insert(ST.root[o], 1, n, val, key); }
int query(int o, int l, int r) {
int ans = 0;
for (; o; o -= lowbit(o)) ans += ST.query(ST.root[o], 1, n, l, r);
return ans;
}
}BT; void work() {
read(n); read(m);
for (int i = 1; i <= n; i++) read(a), BT.add(i, a, 1), ans += BT.query(i-1, a, n), id[a] = i;
for (int i = 1; i <= m; i++) {
writeln(ans); read(a);
ans -= BT.query(id[a]-1, a, n);
ans -= BT.query(n, 1, a);
ans += BT.query(id[a], 1, a);
BT.add(id[a], a, -1);
}
}
int main() {
work(); return 0;
}

解法二

//It is made by Awson on 2018.2.25
#include <bits/stdc++.h>
#define LL long long
#define dob complex<double>
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('\n'))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = 1e5;
void read(int &x) {
char ch; bool flag = 0;
for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
x *= 1-2*flag;
}
void print(LL x) {if (x > 9) print(x/10); putchar(x%10+48); }
void write(LL x) {if (x < 0) putchar('-'); print(Abs(x)); } int n, m, match[N+5], d; LL ans[N+5];
struct tt {int x, y, t, flag; }a[N+5], b[N+5];
struct bittree {
int c[N+5];
void add(int o, int val) {for (; o <= n; o += lowbit(o)) c[o] += val; }
int query(int o) {int ans = 0; for (; o; o -= lowbit(o)) ans += c[o]; return ans; }
}T;
bool comp1(const tt &a, const tt &b) {return a.t < b.t; }
bool comp2(const tt &a, const tt &b) {return a.x < b.x; } void CDQ(int l, int r) {
if (l == r) return; int mid = (l+r)>>1;
for (int i = l; i <= mid; i++) b[i] = a[i], b[i].flag = 1;
for (int i = mid+1; i <= r; i++) b[i] = a[i], b[i].flag = 0;
sort(b+l, b+r+1, comp2);
for (int i = l; i <= r; i++) if (b[i].flag == 1) T.add(b[i].y, 1); else ans[b[i].t] += T.query(n)-T.query(b[i].y);
for (int i = l; i <= r; i++) if (b[i].flag == 1) T.add(b[i].y, -1);
for (int i = r; i >= l; i--) if (b[i].flag == 1) T.add(b[i].y, 1); else ans[b[i].t] += T.query(b[i].y);
for (int i = l; i <= r; i++) if (b[i].flag == 1) T.add(b[i].y, -1);
CDQ(l, mid), CDQ(mid+1, r);
}
void work() {
read(n), read(m); for (int i = 1; i <= n; i++) read(a[i].y), a[i].x = i, match[a[i].y] = i; int times = n;
for (int i = 1; i <= m; i++) read(d), a[match[d]].t = times--;
for (int i = 1; i <= n; i++) if (a[i].t == 0) a[i].t = times--;
sort(a+1, a+n+1, comp1); CDQ(1, n);
LL Ans = 0; for (int i = 1; i <= n; i++) Ans += ans[i];
for (int i = n; i > n-m; i--) writeln(Ans), Ans -= ans[i];
}
int main() {
work(); return 0;
}

[CQOI 2011]动态逆序对的更多相关文章

  1. cdq分治(hdu 5618 Jam's problem again[陌上花开]、CQOI 2011 动态逆序对、hdu 4742 Pinball Game、hdu 4456 Crowd、[HEOI2016/TJOI2016]序列、[NOI2007]货币兑换 )

    hdu 5618 Jam's problem again #include <bits/stdc++.h> #define MAXN 100010 using namespace std; ...

  2. BZOJ 3295: [Cqoi2011]动态逆序对

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3865  Solved: 1298[Submit][Sta ...

  3. Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2886  Solved: 924[Submit][Stat ...

  4. 【Luogu1393】动态逆序对(CDQ分治)

    [Luogu1393]动态逆序对(CDQ分治) 题面 题目描述 对于给定的一段正整数序列,我们定义它的逆序对的个数为序列中ai>aj且i < j的有序对(i,j)的个数.你需要计算出一个序 ...

  5. 【BZOJ3295】动态逆序对(线段树,树状数组)

    [BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...

  6. bzoj3295[Cqoi2011]动态逆序对 树套树

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 5987  Solved: 2080[Submit][Sta ...

  7. P3157 [CQOI2011]动态逆序对(树状数组套线段树)

    P3157 [CQOI2011]动态逆序对 树状数组套线段树 静态逆序对咋做?树状数组(别管归并QWQ) 然鹅动态的咋做? 我们考虑每次删除一个元素. 减去的就是与这个元素有关的逆序对数,介个可以预处 ...

  8. P3157 [CQOI2011]动态逆序对

    P3157 [CQOI2011]动态逆序对 https://www.luogu.org/problemnew/show/P3157 题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai&g ...

  9. 2018.07.01 BZOJ3295: [Cqoi2011]动态逆序对(带修主席树)

    3295: [Cqoi2011]动态逆序对 **Time Limit: 10 Sec Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j& ...

随机推荐

  1. Python读取配置文件,并连接数据库SQL Server

    用配置文件保存固定的连接数据,改的话比较方便. 1.新建一个配置文件:SQlconfig.config,以数据库为例. 内容如下,当然也可以添加多个 [Database1] database=db_t ...

  2. Beta第六天

    听说

  3. 网络1712--c语言函数作业总结

    作业亮点 1.总体情况 很多同学在思路方面大部分写的都很详细,能够通过思路回顾自己的代码 大部分同学都认真完成PTA,也充分利用了函数来解题 大部分同学能够从上机考试中总结自己的失误和不足点,制订了自 ...

  4. 大数据技术Hadoop笔试题

    Hadoop有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上.以下是由应届毕业生网小编J.L为您整理推荐的面试笔试题目和经验,欢迎参考阅读. 单项选择题 1. 下面哪个程序负责 H ...

  5. EL表达式 与 servlvet3.0的新规范

    EL表达式 EL表达式 是一种简化的数据访问方式,是对jsp脚本的简化  . 如我们在一个页面中需要输出session的保存的一个值: <%  out.println(session.getAt ...

  6. 0基础菜鸟学前端之Vue.js

    简介:0基础前端菜鸟,啃了将近半月前端VUE框架,对前端知识有了初步的了解.下面总结一下这段时间的学习心得. 文章结构 前端基础 Vue.js简介 Vue.js常用指令 Vue.js组件 Vue.js ...

  7. DES加密实现的思想及代码

    感谢: http://blog.csdn.net/yxstars/article/details/38424021 上面的日志非常清晰的写出了这个DES加密的过程,主要存在初始IP置换,然后中间存在8 ...

  8. Angular 学习笔记 (路由外传 - RouteReuseStrategy)

    refer : https://github.com/angular/angular/issues/10929 https://stackoverflow.com/questions/41280471 ...

  9. GIT入门笔记(18)- 标签创建和管理

    git tag <name>用于新建一个标签,默认为HEAD,也可以指定一个commit id: git tag -a <tagname> -m "blablabla ...

  10. Flow简易教程——安装篇

    .mydoc_h1{ margin: 0 0 1em; } .mydoc_h1_a{ color: #2c3e50; text-decoration: none; font-size: 2em; } ...