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. 【代码笔记】iOS-点击一个按钮会出现多个按钮的动画效果

    一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...

  2. ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局

    本文转自 :http://www.cnblogs.com/wendingding/p/3761730.html ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布 ...

  3. 网络编程2--毕向东java基础教程视频学习笔记

    Day 23 08 Udp接收端09 Udp键盘录入数据方式10 Udp聊天11 TCP传输12 TCP传输213 TCP练习14 TCP复制文件 08 Udp接收端 需求:定义一个应用程序,用于接收 ...

  4. Asp.net MVC验证哪些事(3)-- Remote验证及其改进(附源码)

    表单中的输入项,有些是固定的,不变的验证规则,比如字符长度,必填等.但有些是动态的,比如注册用户名是否存在这样的检查,这个需要访问服务器后台才能解决.这篇文章将会介绍MVC中如何使用[RemoteAt ...

  5. JavaScript Patterns 5.8 Chaining Pattern

    Chaining Pattern - Call methods on an object one after the other without assigning the return values ...

  6. Oracle global database name与db link的纠缠关系

    ORACLE数据库中Global Database Name与DB LINKS的关系还真是有点纠缠不清,在说清楚这个关系前,我们先来了解一下Global Database Name的概念 Global ...

  7. 已知2个一维数组:a[]={3,4,5,6,7},b[]={1,2,3,4,5,6,7};把数组a与数组b ,对应的元素乘积再赋值给数组b,如:b[2]=a[2]*b[2];最后输出数组b的元素。

    int[]a={3,4,5,6,7}; int[]b={1,2,3,4,5,6,7}; int[] arry=new int[7]; System.out.print("数组b[]={&qu ...

  8. Hadoop+MongoDB的四种方案

    背景: 公司核心业务库现存在MongoDB中,分布在6台MongoDB节点.现面临如下问题: 1.最大的一张表有10多个G,MongoDB在查询方面尚能胜任,但是涉及到复杂计算时会比较吃力. 2.Mo ...

  9. SQL与NoSQL(关系型与非关系型)数据库的区别

    永远正确的经典答案依然是:具体问题具体分析. 数据表VS.数据集 关系型和非关系型数据库的主要差异是数据存储的方式.关系型数据天然就是表格式的,因此存储在数据表的行和列中.数据表可以彼此关联协作存储, ...

  10. 烂泥:nginx同时支持asp.net与php

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 经过两天的实验,终于让nginx同时支持asp.net与php了.下面就把具体的配置过程记录如下. 注意:本次实验OS:centos6 64bit. 尽 ...