P3157 [CQOI2011]动态逆序对

题目描述

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

输入输出格式

输入格式:

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

输出格式:

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

说明

\(N\le 100000,M\le 50000\)


万年以前树套树怎么都是60pts,今天终于决定进行CDQ分治水过去。

每个元素安排三个属性为\(P_i,A_i,D_i\)分别代表在原序列的位置,元素值和被删时间。

然后我们统计一下\(P_i < P_j,A_i>A_j,D_i<D_j\)的个数。

然后我调了半个多小时...

终于弄明白\(P_i > P_j,A_i<A_j,D_i<D_j\)也要统计...


Code:

#include <cstdio>
#include <algorithm>
#define ll long long
const int N=1e5+10;
struct node{int a,b,p;}sq[N];
int n,m,s[N];
ll ans[N];
void add(int x,int d){while(x<=m)s[x]+=d,x+=x&-x;}
int ask(int x){int sum=0;while(x)sum+=s[x],x-=x&-x;return sum;}
bool cmp1(node n1,node n2){return n1.a>n2.a;}
bool cmp2(node n1,node n2){return n1.a<n2.a;}
void CDQ(int l,int r)
{
if(l==r) return;
int mid=l+r>>1;
CDQ(l,mid),CDQ(mid+1,r);
std::sort(sq+l,sq+r+1,cmp1);
for(int i=l;i<=r;i++)
{
if(sq[i].p<=mid) add(sq[i].b,1);
else ans[sq[i].b]+=1ll*(ask(m)-ask(sq[i].b-1));
}
for(int i=l;i<=r;i++) if(sq[i].p<=mid) add(sq[i].b,-1);
std::sort(sq+l,sq+r+1,cmp2);
for(int i=l;i<=r;i++)
{
if(sq[i].p>mid) add(sq[i].b,1);
else ans[sq[i].b]+=1ll*(ask(m)-ask(sq[i].b-1));
}
for(int i=l;i<=r;i++) if(sq[i].p>mid) add(sq[i].b,-1);
}
int main()
{
scanf("%d%d",&n,&m);
for(int a,i=1;i<=n;i++)
{
scanf("%d",&a);
sq[a].a=i;
sq[a].b=m;
sq[a].p=a;
}
for(int a,i=1;i<=m;i++)
{
scanf("%d",&a);
sq[a].b=i;
}
CDQ(1,n);
ans[m]>>=1;
for(int i=m-1;i;i--) ans[i]+=ans[i+1];
for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);
return 0;
}

2018.11.27

洛谷 P3157 [CQOI2011]动态逆序对 解题报告的更多相关文章

  1. 洛谷 P3157 [CQOI2011]动态逆序对(树套树)

    题面 luogu 题解 树套树(树状数组套动态开点线段树) 静态使用树状数组求逆序对就不多说了 用线段树代替树状数组,外面套树状数组统计每个点逆序对数量 设 \(t1[i]\)为\(i\)前面有多少个 ...

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

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

  3. 洛谷P3157 [CQOI2011]动态逆序对

    题目大意: 给定\(1\)到\(n\)的一个排列,按照给定顺序依次删除\(m\)个元素,计算每个元素删除之前整个序列的逆序对数量 基本套路:删边变加边 那么我们不就是求满足\(pos_i<pos ...

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

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

  5. P3157 [CQOI2011]动态逆序对

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

  6. P3157 [CQOI2011]动态逆序对 (CDQ解决三维偏序问题)

    P3157 [CQOI2011]动态逆序对 题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任 ...

  7. [Luogu P3157][CQOI2011]动态逆序对 (树套树)

    题面 传送门:[CQOI2011]动态逆序对 Solution 一开始我看到pty巨神写这套题的时候,第一眼还以为是个SB题:这不直接开倒车线段树统计就完成了吗? 然后冷静思考了一分钟,猛然发现单纯的 ...

  8. luogu P3157 [CQOI2011]动态逆序对(CDQ分治)

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

  9. LUOGU P3157 [CQOI2011]动态逆序对(CDQ 分治)

    传送门 解题思路 cdq分治,将位置看做一维,修改时间看做一维,权值看做一维,然后就转化成了三维偏序,用排序+cdq+树状数组.注意算删除贡献时要做两次cdq,分别算对前面和后面的贡献. #inclu ...

随机推荐

  1. SQL创建数据库、建表、填入内容

    --创建数据库 create database Information go --使用数据库 use Information go --创建表 create table Student ( Sno ) ...

  2. Sublime Text3.0的安装

    Sublime Text是一款轻量级的易于使用的前端编写软件,个人比较推荐. 找到Sublime的官网,下载对应的版本后,点击安装.安装完成后需要下载相应的插件才能进行更加 有效率的开发工作.编写前端 ...

  3. oss上传文件0字节

    最近使用oss上传文件,不同项目中使用的版本也不同,之前的都能正常上传,最近因需要添加ObjectMetaData属性,扩展了一个方法,发现上传的文件始终是0字节的,最终跟源码发现conntentLe ...

  4. Java or Python?测试开发工程师如何选择合适的编程语言?

    很多测试开发工程师尤其是刚入行的同学对编程语言和技术栈选择问题特别关注,毕竟掌握一门编程语言要花不少时间成本,也直接关系到未来的面试和就业(不同企业/项目对技术栈要求也不一样),根据自身情况做一个相对 ...

  5. nodejs express 加载html模板

    在nodejs中如使用express框架,她默认的是ejs和jade渲染模板.由于我在使用的时候觉得她的代码书写方式很不爽还是想用html的形式去书写,于是我找了使用了html模板. 直接上代码,主要 ...

  6. v-for 指令

    JS部分: var app = new Vue({ el: "#app", data() { return { list: [1, 2, 3, 4], objList: [ { i ...

  7. zabbix_agentd-install.sh (脚本部署zabbix_agentd服务)

    原文发表于cu:2016-05-20 基于http://www.cnblogs.com/netonline/p/7406598.html(http://blog.chinaunix.net/uid-2 ...

  8. UVa 10071

    简单运动学公式 v=v0+at x=v0t+1/2*a*t^2=2vt #include<stdio.h> int main() { int v, t; while((scanf(&quo ...

  9. Python基础灬列表&字典生成式

    列表生成式 # 求1~10偶数的平方 # 1.常规写法 a_list = [] for i in range(1, 11): if i % 2 == 0: a_list.append(i * i) p ...

  10. 常用DOS指令备忘

    1.删除整个目录,包括空目录 rd D:\管理\2012新同学练习\.svn /s/q /s 删除当前目录及子目录 /q 不询问直接删除 2.拷贝目录树 xcopy D:\管理\2012新同学练习 E ...