题目大意:

给定\(1\)到\(n\)的一个排列,按照给定顺序依次删除\(m\)个元素,计算每个元素删除之前整个序列的逆序对数量

基本套路:删边变加边

那么我们不就是求满足\(pos_i<pos_j,tim_i<tim_j,num_i>num_j\)的数量嘛

先按\(tim\)排序,然后归并\(pos_i\),树状数组\(num_i\)

不过这道题我们需要正反跑两个\(cdq\),因为我们需要分开统计\(pos_i<pos_j,num_i>num_j\)和\(pos_i>pos_j,num_i<num_j\)的贡献

但是我压缩到一个\(cdq\)里了\(emmmm\)

需要稍微注意的一点是,我们需要把答案累加的令一个\(ret_i\)数组中,其中\(ret_i\)表示在\(i\)时刻新产生了多少逆序对,最后还需要输出前缀和

不粘代码是不是太短了

#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define mid ((l+r)>>1)
#define lowbit(x) ((x)&(-x))
inline int read()
{
int x=0;char ch,f=1;
for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
if(ch=='-') f=0,ch=getchar();
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f?x:-x;
}
const int N=1e5+10;
int n,m,idx,tot;
int pos[N];
int st[N];
int ret[N];
struct point
{
int x,id,tim;
int val;
inline bool operator < (const point &t) const
{
if(tim^t.tim) return tim<t.tim;
return id<t.id;
}
}a[N<<2],t[N<<2];
int tr[N<<1];
inline void update(int x,int k)
{
for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=k;
}
inline int query(int y)
{
int ret=0;
for(int i=y;i;i-=lowbit(i))
ret+=tr[i];
return ret;
}
inline void cdq(int l,int r)
{
if(l==r) return;
cdq(l,mid);
cdq(mid+1,r);
int tl=l,tr=mid+1,tot=l;
while(tl<=mid&&tr<=r)
{
if(a[tl].id<=a[tr].id) update(a[tl].x,1),t[tot++]=a[tl++];
else ret[a[tr].tim]+=query(n)-query(a[tr].x),t[tot++]=a[tr++];
}
while(tl<=mid) update(a[tl].x,1),t[tot++]=a[tl++];
while(tr<=r) ret[a[tr].tim]+=query(n)-query(a[tr].x),t[tot++]=a[tr++];
for(int i=l;i<=mid;++i) update(a[i].x,-1);
tl=mid,tr=r;
while(tl>=l&&tr>=mid+1)
{
if(a[tl].id>=a[tr].id) update(a[tl].x,1),--tl;
else ret[a[tr].tim]+=query(a[tr].x-1),--tr;
}
while(tl>=l) update(a[tl].x,1),--tl;
while(tr>=mid+1) ret[a[tr].tim]+=query(a[tr].x-1),--tr;
for(int i=l;i<=mid;++i) update(a[i].x,-1);
for(int i=l;i<=r;++i) a[i]=t[i];
}
inline void main()
{
n=read(),m=read();
for(int x,i=1;i<=n;++i)
{
x=read();
pos[x]=i;
a[i].x=x;
a[i].id=i;
a[i].tim=1;
}
for(int x,tmp,i=1;i<=m;++i)
{
x=read();
tmp=pos[x];
a[tmp].tim=m-i+2;
}
sort(a+1,a+n+1);
cdq(1,n);
for(int i=1;i<=m+1;++i) ret[i]+=ret[i-1];
for(int i=m+1;i>=2;--i) printf("%lld\n",ret[i]);
}
}
signed main()
{
red::main();
return 0;
}

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

  1. 洛谷 P3157 [CQOI2011]动态逆序对 解题报告

    P3157 [CQOI2011]动态逆序对 题目描述 对于序列\(A\),它的逆序对数定义为满足\(i<j\),且\(A_i>A_j\)的数对\((i,j)\)的个数.给\(1\)到\(n ...

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

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

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

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

  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]动态逆序对

    题目链接 \(Click\) \(Here\) 这个题有点卡常数..我的常数比较大所以是吸着氧气跑过去的... 题意:计算对于序列中每个位置\(p\),\([1,p-1]\)区间内比它大的数的个数,和 ...

随机推荐

  1. 用arthas的watch方法观察执行方法的输入输出

    watch 的参数比较多,主要是因为它能在 4 个不同的场景观察对象 参数名称 参数说明 class-pattern 类名表达式匹配 method-pattern 方法名表达式匹配 express 观 ...

  2. CF1269A Equation

    题目链接 题意 要找两个合数,使他们两个的差为\(n\),\(n\)为题目给出的数 思路 我们可以枚举减数\(now\),判断一下是不是质数,如果是质数就让\(now++\),然后用一个数\(tot\ ...

  3. Codeforces Round #597 (Div. 2) E. Hyakugoku and Ladders 概率dp

    E. Hyakugoku and Ladders Hyakugoku has just retired from being the resident deity of the South Black ...

  4. CSP-S 2019初赛前后小记

    Preface 做完了初赛前的最后一场模拟赛,虽然这场做的挺好.但由于之前的一场难度很高,再加上自己犯了一些ZZ错误因此对初赛也有了一些不安之情 想起去年自己对于初赛的态度,实在是愧疚虽然去年文化课弃 ...

  5. find与rm实现查找并删除目录或文件

    linux 下用find命令查找文件,rm命令删除文件. 删除指定目录下指定文件find 要查找的目录名 -name .svn |xargs rm -rf 删除指定名称的文件或文件夹: find -t ...

  6. git分支合并解决冲突

    git分支合并,解决冲突 1.手动解决冲突 手动解决冲突,需要使用编辑器,把所有文件中出现的冲突地方修改,然后再添加到暂存区再提交 >>>>>>brancha so ...

  7. win7和win10自带桌面便签哪里找

    一些小伙伴习惯使用windows自带的便签功能,但win7和win10区别较大, 导致更新系统后不知道在哪里找,甚至以为没有该功能了, 其实不然,下面我总结了2种方法,希望能帮到有需要的人 win7( ...

  8. HTML5 Canvas 为网页添加文字水印

    <!DOCTYPE html> <html> <body> <canvas id=" style="border:1px solid #d ...

  9. requests库的使用、安装及方法的简单介绍

    requests库的使用.安装及方法的简单介绍 1.requests库的概述 requests库是一个简洁且简单的处理HTTP请求的第三方库,是公认的最好获得第三方信息的库. requests库更多信 ...

  10. ASP.NET Core框架深度学习(二) 管道对象

    4.HttpContext 第一个对象 我们的ASP.NET Core Mini由7个核心对象构建而成.第一个就是大家非常熟悉的HttpContext对象,它可以说是ASP.NET Core应用开发中 ...