【bzoj3295】[Cqoi2011]动态逆序对

2014年6月17日4,7954

Description

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

Input

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

Output

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

Sample Input

5 4
1
5
3
4
2
5
1
4
2

Sample Output

5
2
2
1
样例解释
(1,5,3,4,2)(1,3,4,2)(3,4,2)(3,2)(3)。

HINT

N<=100000 M<=50000

题解:

    这道动态逆序对问题和普通逆序对问题有什么区别,发现动态逆序对的每个值还有一个时间影响

    普通逆序对只有两个元素是二维偏序问题,一维是位置,一维是键值。

    而这里就是三维偏序问题,我们应该怎么来安排可以最方便呢?

    我是这样安排的,a,b,c分别表示时间,位置,键值,分别排序+cdq+树状数组,这样来搞

    在对于键值中,有点技巧,应为位置可能在前或者在后面,所以两次树状数组维护才行。

    最后用前缀和的思想。

 #include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstdio> #define N 100007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if (ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int n,m,tr[N];
long long ans[N];
struct Node
{
int a,b,c,ans;
}a[N]; bool cmp1(Node x,Node y)
{
if (x.a==y.a&&x.b==y.b) return x.c>y.c;
if (x.a==y.a) return x.b<y.b;
return x.a<y.a;
}
bool cmp2(Node x,Node y)
{
return x.b<y.b;
}
bool cmp3(Node x,Node y)
{
return x.b>y.b;
}
int lowbit(int x){return x&(-x);}
void update(int x,int num)
{
for (int i=x;i<=n;i+=lowbit(i))
tr[i]+=num;
}
int query(int x)
{
int res=;
for (int i=x;i>=;i-=lowbit(i))
res+=tr[i];
return res;
}
void cdq(int l,int r)
{
if (l==r) return;
int mid=(l+r)>>;
cdq(l,mid);
cdq(mid+,r);
sort(a+l,a+mid+,cmp2);
sort(a+mid+,a+r+,cmp2);
int i=l,j=mid+;
while(j<=r)
{
while(i<=mid&&a[i].b<a[j].b)
update(a[i].c,),i++;
a[j].ans+=query(n)-query(a[j].c),j++;
}
for (int j=l;j<i;j++)
update(a[j].c,-); sort(a+l,a+mid+,cmp3);
sort(a+mid+,a+r+,cmp3);
i=l,j=mid+;
while(j<=r)
{
while(i<=mid&&a[i].b>a[j].b)
update(a[i].c,),i++;
a[j].ans+=query(a[j].c),j++;
}
for (int j=l;j<i;j++)
update(a[j].c,-);
}
int main()
{
n=read(),m=read();
for (int i=;i<=n;i++){int x=read();a[x].b=i;}
for (int i=;i<=m;i++){int x=read();a[x].a=m-i+;}//倒着表示什么时候插入
for (int i=;i<=n;i++)a[i].c=i;
sort(a+,a+n+,cmp1);
cdq(,n);
for (int i=;i<=n;i++)
ans[a[i].a]+=a[i].ans;
for (int i=;i<=m;i++)
ans[i]+=ans[i-];
for (int i=m;i>=;i--)
printf("%lld\n",ans[i]);
}

bzoj3295 [Cqoi2011]动态逆序对 cdq+树状数组的更多相关文章

  1. BZOJ3295: [Cqoi2011]动态逆序对(树状数组套主席树)

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

  2. BZOJ3295 [Cqoi2011]动态逆序对 分治 树状数组

    原文链接http://www.cnblogs.com/zhouzhendong/p/8678185.html 题目传送门 - BZOJ3295 题意 对于序列$A$,它的逆序对数定义为满足$i< ...

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

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

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

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

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

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

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

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

  7. BZOJ3295 动态逆序对(树状数组套线段树)

    [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6058  Solved: 2117[Submit][Status][D ...

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

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

  9. bzoj3295: [Cqoi2011]动态逆序对(树套树)

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

随机推荐

  1. Toasts官方教程

    Toasts IN THIS DOCUMENT The Basics Positioning your Toast Creating a Custom Toast View 在其它线程中启动Toast ...

  2. SimpleDateForma类

    package Format_daqo; import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDa ...

  3. spark调试环境搭建

    到目前为止,基于RDD的spark streamming实时应用和离线应用(主要解析日志)已经写了一些,但是对spark的了解还是很少,所以决心花点精力,对spark做一些比较深入的了解和学习.参照之 ...

  4. [转]Open Data Protocol (OData) Basic Tutorial

    本文转自:http://www.odata.org/getting-started/basic-tutorial/ Basic Tutorial The Open Data Protocol (ODa ...

  5. 设置电脑IP

    1.首先在Win7桌面上找到“网络”入口,如下图:   进入Win7网络 2.进入网络之后我们再点击顶部的“网络共享中心”,如下图:   进入Win7网络共享中心 3.进入Win7网络共享中心之后,我 ...

  6. java封装的优点

    在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装.隐藏起来的方法. 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机 ...

  7. Java 线程 —— Wait (等待)和 Notify(唤醒)

    Wait (等待)和 Notify(唤醒) 这里讲了一个Wait (等待)和 Notfity(唤醒),下面这个实例(工厂,商店,消费者) 额,然后,你就知道了,需要写三个类:工厂类,Shop类,消费者 ...

  8. iOS循环引用

    iOS循环引用 当前类的闭包/Block属性,用到了当前类,就会造成循环引用 此闭包/Block应该是当前类的属性,我们经常对Block进行copy,copy到堆中,以便后用. 单方向引用是不会产生循 ...

  9. windows ubuntu bcdeditor

    双系统. 先装windows,后装ubuntu12.04 为了避免grub引导,所以安装bcdeditor. 平时使用没有什么不适,可是每次linux升级内核以后,grub列表可能就会消失,自然是不能 ...

  10. [6818开发板]八核开发板|4G开发板|GPS开发板|嵌入式开发平台

    IMX6开发板(基本型):960元 IMX6开发板(豪华型):1460元 S5P4418 核心板可以无缝支持核心系统S5P6818,并保持底板设计不变,将兼顾更高端 的应用领域,为项目和产品提供更好的 ...