[CQOI 2011]动态逆序对

时间:2021-03-30 00:46:54

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&&num;39&semi;s problem again&lbrack;陌上花开&rsqb;、CQOI 2011 动态逆序对、hdu 4742 Pinball Game、hdu 4456 Crowd、&lbrack;HEOI2016&sol;TJOI2016&rsqb;序列、&lbrack;NOI2007&rsqb;货币兑换 )

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

  2. BZOJ 3295&colon; &lbrack;Cqoi2011&rsqb;动态逆序对

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

  3. Bzoj 3295&colon; &lbrack;Cqoi2011&rsqb;动态逆序对 分块&comma;树状数组&comma;逆序对

    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&lbrack;Cqoi2011&rsqb;动态逆序对 树套树

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

  7. P3157 &lbrack;CQOI2011&rsqb;动态逆序对(树状数组套线段树)

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

  8. P3157 &lbrack;CQOI2011&rsqb;动态逆序对

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

  9. 2018&period;07&period;01 BZOJ3295&colon; &lbrack;Cqoi2011&rsqb;动态逆序对(带修主席树)

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

随机推荐

  1. CSharpGL&lpar;19&rpar;用glReadPixels把渲染的内容保存为PNG图片&lpar;C&num;&rpar;

    CSharpGL(19)用glReadPixels把渲染的内容保存为PNG图片(C#) 效果图 本文解决了将OpenGL渲染出来的内容保存到PNG图片的方法. 下载 CSharpGL已在GitHub开 ...

  2. STL标准模板库(简介)

    标准模板库(STL,Standard Template Library)是C++标准库的重要组成部分,包含了诸多在计算机科学领域里所常见的基本数据结构和基本算法,为广大C++程序员提供了一个可扩展的应 ...

  3. 【第一篇】ASP&period;NET MVC快速入门之数据库操作(MVC5&plus;EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  4. guava学习--FluentIterable

    public class FluentIterableTest { public static void main(String[] args) { Man man1 = new Man(" ...

  5. 无状态服务(stateless service)

    一.定义 无状态服务(stateless service)对单次请求的处理,不依赖其他请求,也就是说,处理一次请求所需的全部信息,要么都包含在这个请求里,要么可以从外部获取到(比如说数据库),服务器本 ...

  6. &lt&semi;当幸福来敲门&gt&semi;之一些很喜欢的台词收藏

    <当幸福来敲门> ================ ================

  7. SpringMvc笔记-注解

    @RequestParam(value = "username", defaultValue = "haha", required = true) 有四个参数 ...

  8. 最短路径问题(Floyd-Warshall模板)

    #include<bits/stdc++.h> using namespace std; int n; int x,y; ][]; ][]; int m,s,t; int main() { ...

  9. Scala并发编程【进阶】

    package com.dingxin.entrance import java.text.SimpleDateFormat import java.util.Date import scala.ac ...

  10. chattr命令详解

    [root@localhost ~]# usermod -L yan[root@localhost ~]# passwd -S yanyan LK 2016-07-11 0 99999 7 -1 (密 ...