Description

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

Input

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

Output

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

HINT

$n \leq 100000$   $m \leq 50000$

  这道题做法很多……但是我来做这道题只是为了练CDQ分治的……

  首先,我们可以考虑当删除一个数之后逆序对数减少了多少。不难发现,减少的逆序对数就是 这个数 前面比它大的数的个数 加上 后面比它小的数的个数。

  那么,如果我们强行把最后数列中剩下的数也删掉,那么我们就得到了$n$个操作,用 $(x_i,y_i,z_i)$ 表示操作$i$是在时刻$z$把$y$位置上值为$x$的数给删掉。

  于是,对于一个操作$i$,这个操作减少的逆序对数为 $x_j>x_i,y_j<y_i,z_j>z_i$以及$x_j<x_i,y_j>y_i,z_j>z_i$的$j$的个数。

  其实这就是一个三维偏序。对于两个式子分别在CDQ分治的时候扫一遍即可。 大概的思路就是排序一维,分治时归并一维,剩下一维再用树状数组来维护。

  下面贴代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 100010 using namespace std;
typedef long long llg; struct data{
int x,y,b;
bool operator < (const data &h)const{return x>h.x;}
}s[maxn],ss[maxn];
int c[maxn],n,m,a[maxn],ans[maxn];
bool w[maxn]; llg ana; int getint(){
int w=;bool q=;
char c=getchar();
while((c>''||c<'')&&c!='-') c=getchar();
if(c=='-') c=getchar(),q=;
while(c>=''&&c<='') w=w*+c-'',c=getchar();
return q?-w:w;
} void add(int x,int y){while(x<=n) c[x]+=y,x+=x&(-x);}
int sum(int x){
int t=;
while(x) t+=c[x],x-=x&(-x);
return t;
} void solve(int l,int r){
if(l>=r) return;
int mid=l+r>>,now=l,kk=l-,k1=l,k2=mid+;
solve(l,mid); solve(mid+,r);
for(int i=mid+;i<=r;i++){
while(s[now].y<s[i].y && now<=mid) add(s[now].b,),now++;
ans[s[i].b]+=sum(n)-sum(s[i].b);
}
for(int i=l;i<now;i++) add(s[i].b,-);
now=r;
for(int i=mid;i>=l;i--){
while(s[now].y>s[i].y && now>mid) add(s[now].b,),now--;
ans[s[i].b]+=sum(n)-sum(s[i].b);
}
for(int i=now+;i<=r;i++) add(s[i].b,-);
while(k1<=mid && k2<=r)
if(s[k1].y<s[k2].y) ss[++kk]=s[k1++];
else ss[++kk]=s[k2++];
while(k1<=mid) ss[++kk]=s[k1++];
while(k2<=r) ss[++kk]=s[k2++];
for(int i=l;i<=r;i++) s[i]=ss[i];
} int main(){
File("a");
n=getint(); m=getint();
for(int i=;i<=n;i++) a[getint()]=i;
for(int i=;i<=m;i++){
s[i].x=getint(); s[i].b=i;
s[i].y=a[s[i].x]; w[s[i].x]=;
}
for(int i=,t=m;i<=n;i++)
if(!w[i]){
s[++t].x=i; s[t].b=t;
s[t].y=a[s[t].x];
}
sort(s+,s+n+); solve(,n);
for(int i=;i<=n;i++) ana+=ans[i];
for(int i=;i<=m;i++){
printf("%lld\n",ana);
ana-=ans[i];
}
}

BZOJ 3295 【Cqoi2011】 动态逆序对的更多相关文章

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

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

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

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

  3. bzoj 3295 [Cqoi2011]动态逆序对(cdq分治,BIT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3295 [题意] n个元素依次删除m个元素,求删除元素之前序列有多少个逆序对. [思路] ...

  4. 【刷题】BZOJ 3295 [Cqoi2011]动态逆序对

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

  5. bzoj 3295: [Cqoi2011]动态逆序对(树套树 or CDQ分治)

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

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

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

  7. BZOJ 3295 [CQOI2011]动态逆序对 (三维偏序CDQ+树状数组)

    题目大意: 题面传送门 还是一道三维偏序题 每次操作都可以看成这样一个三元组 $<x,w,t>$ ,操作的位置,权值,修改时间 一开始的序列看成n次插入操作 我们先求出不删除时的逆序对总数 ...

  8. BZOJ 3295 [Cqoi2011]动态逆序对 ——CDQ分治

    时间.位置.数字为三个属性. 排序时间,CDQ位置,树状数组处理数字即可. #include <cstdio> #include <cstring> #include < ...

  9. 【BZOJ 3295】动态逆序对 - 分块+树状数组

    题目描述 给定一个1~n的序列,然后m次删除元素,每次删除之前询问逆序对的个数. 分析:分块+树状数组 (PS:本题的CDQ分治解法见下一篇) 首先将序列分成T块,每一块开一个树状数组,并且先把最初的 ...

  10. 【Bzoj 3295】 动态逆序对(树套树|CDQ分治)

    [题意] 每次删除一个数,然后问删除前逆序对数. [分析] 没有AC不开心.. 我的树状数组套字母树,应该是爆空间的,空间复杂度O(nlogn^2)啊..哭.. 然后就没有然后了,别人家的树套树是树状 ...

随机推荐

  1. Swift开发第二篇——extension及fatalError

    本篇分两部分: 一.extension在 Swift 中的使用 二.Swift 中的 fatalError 一.extension在 Swift 中的使用 在 swift 中我们可以通过 extens ...

  2. Xcode常用快捷键的使用

    熟练使用Xcode的一些快捷方式,会大大加快项目开发的速度.

  3. 【转】OpenStack和Docker、ServerLess能不能决定云计算胜负吗?

    还记得在十多年前,SaaS鼻祖SalesForce喊出的口号『No Software』吗?SalesForce在这个口号声中开创了SaaS行业,并成为当今市值460亿美元的SaaS之王.今天谈谈『No ...

  4. 区别和详解:js中call()和apply()的用法

    1.关于call()和apply()的疑点: apply和call的区别在哪里 什么情况下用apply,什么情况下用call apply的其他巧妙用法(一般在什么情况下可以使用apply) 2.语法和 ...

  5. Maven基础配置—上传jar包到私服

    一.配置 在需要上传的工程中的pom.xml文件中加入下面的配置 <distributionManagement> <repository> <id>release ...

  6. 数据库模型设计——历史与版本设计

    在企业数据库设计中,经常会遇到一个需求,就是希望把操作之前的数据保留下来,能够看到操作之前是什么数据,操作之后是什么数据.对于这种需求,我们可以使用保留历史数据或者使用版本来实现. 为了能够保留历史数 ...

  7. ASP.NET MVC 拓展ViewResult实现word文档下载

      最近项目中有同事用到word文档导出功能,遇到了一些导出失败问题,帮其看了下解决问题的同事,看了下之前的代码发现几个问题: 代码编写不规范,word导出功能未收口 重复代码导出都是 实现逻辑比较复 ...

  8. win7下硬盘安装ubuntu

    首先还是分区,在计算机上右键--管理--磁盘管理.装Ubuntu分配的硬盘大小最好是(20G以上)不要太小,这里请注意,Ubuntu和Windows文件系统完全不同,所以我们划好要给Ubuntu的分区 ...

  9. Linux磁盘管理之磁盘结构、概念、原理01

    一.磁盘的分类 磁盘主要有IDE.SATA.SCSI.IDE是比较老的硬盘,数据速度比较慢:SATA是现在用的比较多的,台式机.笔记本大多都用的SATA硬盘:SCSI硬盘速度最快,但是价格相对较高. ...

  10. 客户访问站点将bbs/链接 跳转至forum/链接下的两种方式

    显性 302 暂时重定向跳转 server { listen 80 ; server_name localhost; index index.html index.htm index.php; roo ...