题目

对于序列A,它的逆序对数定义为满足i

输入格式

输入第一行包含两个整数n和m,即初始元素的个数和删除的元素个数。以下n行每行包含一个1到n之间的正整数,即初始排列。以下m行每行一个正整数,依次为每次删除的元素。

输出格式

输出包含m行,依次为删除每个元素之前,逆序对的个数。

输入样例

5 4

1

5

3

4

2

5

1

4

2

输出样例

5

2

2

1

样例解释

(1,5,3,4,2)(1,3,4,2)(3,4,2)(3,2)(3)。

提示

N<=100000 M<=50000

题解

反过来插入元素

对于每个元素,对应一个三元组(t,x,y),表示t时刻插入,位置x,权值y

每个元素插入时产生的逆序对数量为所有的满足如下条件的(t’,x’,y’)

t’ < t 且 x’ > x 且 y’ <y

或者 t’ < t 且 x’ < x 且 y’ > y

这就是三维偏序,可以用CDQ分治

因为有两种情况,所以要正反统计两次

压行代码50行不到,CDQ很感人】

#include<iostream>
#include<cstdio>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define lbt(x) (x & -x)
using namespace std;
const int maxn = 100005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}
return out * flag;
}
struct Que{int t,x,y;}Q[maxn],T[maxn];
inline bool operator <(const Que& a,const Que& b){return a.x > b.x;}
int N,M,A[maxn],B[maxn],C[maxn],cnt,Qi,s[maxn];
LL ans[maxn];
void add(int u,int v){while (u <= N) s[u] += v,u += lbt(u);}
int query(int u){int Ans = 0; while (u) Ans += s[u],u -= lbt(u); return Ans;}
void cdq(int l,int r){
if (l == r) return;
int mid = l + r >> 1,l1 = l,l2 = mid + 1;
for (int i = l; i <= r; i++)
if (Q[i].t <= mid) add(Q[i].y,1);
else ans[Q[i].t] += query(Q[i].y);
for (int i = l; i <= r; i++)
if (Q[i].t <= mid) add(Q[i].y,-1);
for (int i = r; i >= l; i--)
if (Q[i].t <= mid) add(N - Q[i].y + 1,1);
else ans[Q[i].t] += query(N - Q[i].y + 1);
for (int i = l; i <= r; i++)
if (Q[i].t <= mid) T[l1++] = Q[i],add(N - Q[i].y + 1,-1);
else T[l2++] = Q[i];
for (int i = l; i <= r; i++) Q[i] = T[i];
cdq(l,mid); cdq(mid + 1,r);
}
int main(){
cnt = N = read(); M = read();
REP(i,N) B[A[i] = read()] = i;
REP(i,M){C[Q[i].x = B[Q[i].y = read()]] = true; Q[i].t = cnt--; ++Qi;}
REP(i,N) if (!C[i]) Q[++Qi] = (Que){cnt--,i,A[i]};
sort(Q + 1,Q + 1 + N);
cdq(1,N);
REP(i,N) ans[i] += ans[i - 1];
for (int i = 0; i < M; i++) printf("%lld\n",ans[N - i]);
return 0;
}

BZOJ3295 [Cqoi2011]动态逆序对 【CDQ分治】的更多相关文章

  1. [BZOJ3295][Cqoi2011]动态逆序对 CDQ分治&树套树

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

  2. bzoj3295: [Cqoi2011]动态逆序对(cdq分治+树状数组)

    3295: [Cqoi2011]动态逆序对 题目:传送门 题解: 刚学完cdq分治,想起来之前有一道是树套树的题目可以用cdq分治来做...尝试一波 还是太弱了...想到了要做两次cdq...然后伏地 ...

  3. BZOJ3295 [Cqoi2011]动态逆序对 —— CDQ分治

    题目链接:https://vjudge.net/problem/HYSBZ-3295 3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 1 ...

  4. BZOJ3295:[CQOI2011]动态逆序对(CDQ分治)

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

  5. 【BZOJ3295】[Cqoi2011]动态逆序对 cdq分治

    [BZOJ3295][Cqoi2011]动态逆序对 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依 ...

  6. bzoj3295 [Cqoi2011]动态逆序对 cdq+树状数组

    [bzoj3295][Cqoi2011]动态逆序对 2014年6月17日4,7954 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数. ...

  7. [CQOI2011]动态逆序对 CDQ分治

    洛谷上有2道相同的题目(基本是完全相同的,输入输出格式略有不同) ---题面--- ---题面--- CDQ分治 首先由于删除是很不好处理的,所以我们把删除改为插入,然后输出的时候倒着输出即可 首先这 ...

  8. 洛谷 P3157 [CQOI2011]动态逆序对 | CDQ分治

    题目:https://www.luogu.org/problemnew/show/3157 题解: 1.对于静态的逆序对可以用树状数组做 2.我们为了方便可以把删除当成增加,可以化动为静 3.找到三维 ...

  9. BZOJ 3295: [Cqoi2011]动态逆序对 [CDQ分治]

    RT 传送门 首先可以看成倒着插入,求逆序对数 每个数分配时间(注意每个数都要一个时间)$t$,$x$位置,$y$数值 $CDQ(l,r)$时归并排序$x$ 然后用$[l,mid]$的加入更新$[mi ...

  10. P3157 [CQOI2011]动态逆序对 CDQ分治

    一道CDQ分治模板题简单来说,这道题是三维数点对于离线的二维数点,我们再熟悉不过:利用坐标的单调递增性,先按更坐标排序,再按纵坐标排序更新和查询时都直接调用纵坐标.实际上,我们是通过排序将二维中的一维 ...

随机推荐

  1. DongDong坐飞机

    题目连接:https://ac.nowcoder.com/acm/contest/904/D 第一次研究了一下这种题型,还是比较好理解的,因为有半价次数的限制,所以要把每一中情况都写出来,dp[现在的 ...

  2. web项目小总结

     初步小结 1.之前的CSS有些遗忘,返回去重新看知识点,频繁会浪费项目时间. 比如说: position定位 1 position: absolute;//绝对定位 2 position:relat ...

  3. 零基础快速入门SpringBoot2.0 (一)

    零基础快速入门SpringBoot2.0 (一) 一.SpringBoot2.x依赖环境和版本新特性说明 简介:讲解新版本依赖环境和springboot2新特性概述 1.依赖版本jdk8以上, Spr ...

  4. SQL SERVER 2012数据库自动备份的方法

    SQL SERVER 2012数据库自动备份的方法 为了防止数据丢失,这里给大家介绍SQL SERVER2012数据自动备份的方法: 一.打开SQL SERVER 2012,如图所示: 服务器类型:数 ...

  5. 2017年9月11日 梁勇 java教材 编程练习题 第二章 2.15 键盘 读取两个点的坐标值(小数),控制台输出两点间距离。

    package com.swift; import java.util.Scanner; public class PToP { public static void main(String[] ar ...

  6. 关于debug

    2019-04-05  11:18:15 1. debug 需巧用两个工具 1.1  用‘#’把感觉会出错的代码段注释掉 多行注释有两种快捷操作: 在需要注释的多行代码块前后加一组三引号''' 选中代 ...

  7. 用Python和WordCloud绘制词云(内附让字体清晰的秘笈)

    环境及模块: Win7 64位 Python 3.6.4 WordCloud 1.5.0 Pillow 5.0.0 Jieba 0.39 目标: 绘制安徽省2018年某些科技项目的词云,直观展示热点. ...

  8. 使用HTTP协议访问网络

    在Android上发送http请求有2种方式,分别由两个类完成,HttpURLConnection和HttpClient. 一.使用HttpURLConnection方式 1.1 建立连接的基本步骤 ...

  9. CyclicBarrier源码分析

    CyclicBarrier是通过ReentrantLock(独占锁)和Condition来实现的.下面,我们分析CyclicBarrier中3个核心函数: 构造函数, await()作出分析. 1. ...

  10. Java文件 ---流

    分类 根据数据走向,分为输入流.输出流 根据处理的数据类型,分为字节流.字符流 字节流 可以处理所有类型的数据,如MP3.图片.文字.视频等.在读取时,读到一个字节就返回一个字节. 在Java中对应的 ...