传送门

题解

听别人说这是洛谷用户的双倍经验啊……然而根本没有感觉到……因为另外的那题我是用树状数组套主席树做的……而且莫名其妙感觉那种方法思路更清晰(虽然码量稍稍大了那么一点点)……感谢Candy大佬教会了我CDQ的动态逆序对……莫名其妙1A了……

因为是删除,所以可以看成倒着加入。而且没规定都在$n$以内,所以要离散。我们把每一个位置都表示成一个三元组$(t,x,y)$,其中$t$表示加入的时间,$x$表示在原数组中的位置,$y$表示离散之后的值。求逆序对,就代表求有多少个三元组满足$t'<t,x'<x,y'>y$或$t'<t,x'>x,y'<y$。我们可以先把时间这一维排序,然后CDQ的时候顺便排好$x$这一维,$y$这一维用树状数组求解。因为要找两种,所以CDQ的时候要两个分别找,这一部分的细节可以参考代码

 //minamoto
#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(ll x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]=' ';
}
const int N=4e4+;
int n,m,c[N],ty,yy[N];
inline void add(int x,int val){
for(;x<=ty;x+=x&-x) c[x]+=val;
}
inline int query(int x){
int res=;
for(;x;x-=x&-x) res+=c[x];
return res;
}
inline void clear(int x){
for(;x<=ty;x+=x&-x)
if(c[x]) c[x]=;else break;
}
struct node{
int t,x,y;
node(){}
node(int t,int x,int y):t(t),x(x),y(y){}
bool operator <(const node &b)const
{return x==b.x?y<b.y:x<b.x;}
}a[N],p[N];
inline bool cmptime(const node &a,const node &b){
return a.t==b.t?a.x<b.x:a.t<b.t;
}
ll ans[N];
void CDQ(int l,int r){
if(l==r) return;
int mid=l+r>>;
CDQ(l,mid),CDQ(mid+,r);
for(int i=l,j=l,k=mid+;i<=r;){
if(k>r||(j<=mid&&a[j]<a[k])) add(a[j].y,),p[i++]=a[j++];
else ans[a[k].t]+=query(n)-query(a[k].y),p[i++]=a[k++];
}
for(int i=l;i<=mid;++i) clear(a[i].y);
for(int i=l;i<=r;++i) a[i]=p[i];
for(int i=r;i>=l;--i){
if(a[i].t<=mid) add(a[i].y,);
else ans[a[i].t]+=query(a[i].y-);
}
for(int i=l;i<=r;++i) clear(a[i].y);
}
int main(){
//freopen("testdata.in","r",stdin);
n=read(),m=read();
for(int i=;i<=n;++i){
yy[i]=read(),a[i]=node(,i,yy[i]);
}
sort(yy+,yy++n);
ty=unique(yy+,yy++n)-yy-;
for(int i=;i<=n;++i) a[i].y=lower_bound(yy+,yy++ty,a[i].y)-yy;
int Time=n;
for(int i=;i<=m;++i){
int k=read();a[k].t=Time--;
}
for(int i=;i<=n;++i) if(!a[i].t) a[i].t=Time--;
sort(a+,a++n,cmptime);
CDQ(,n);
for(int i=;i<=n;++i) ans[i]+=ans[i-];
for(int i=n;i>=n-m;--i) print(ans[i]);
Ot();
return ;
}

洛谷P1393 动态逆序对(CDQ分治)的更多相关文章

  1. P3157 动态逆序对 CDQ分治

    动态逆序对 CDQ分治 传送门:https://www.luogu.org/problemnew/show/P3157 题意: 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对 ...

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

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

  3. BZOJ 3295 动态逆序对 | CDQ分治

    BZOJ 3295 动态逆序对 这道题和三维偏序很类似.某个元素加入后产生的贡献 = time更小.pos更小.val更大的元素个数 + time更小.pos更大.val更小的元素个数. 分别用类似C ...

  4. 【BZOJ3295】[Cqoi2011]动态逆序对 cdq分治

    [BZOJ3295][Cqoi2011]动态逆序对 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依 ...

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

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

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

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

  7. 洛谷P3157 动态逆序对 [CQOI2011] cdq分治

    正解:cdq分治 解题报告: 传送门! 长得有点像双倍经验还麻油仔细看先放上来QwQ! 这题首先想到的就直接做逆序对,然后记录每个点的贡献,删去就减掉就好 但是仔细一想会发现布星啊,如果有一对逆序对的 ...

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

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

  9. [CQOI2011]动态逆序对 CDQ分治

    洛谷上有2道相同的题目(基本是完全相同的,输入输出格式略有不同) ---题面--- ---题面--- CDQ分治 首先由于删除是很不好处理的,所以我们把删除改为插入,然后输出的时候倒着输出即可 首先这 ...

随机推荐

  1. python 发送带附件的 邮件

    from email.MIMETextimportMIMETextfrom email.MIMEMultipartimportMIMEMultipartimport smtplib mail_host ...

  2. Gerrit 系统初探 (已转移到 https://steemit.com/gerrit/@linvictor88/gerrit )

    Gerrit 使用简介        Gerrit,一种免费.开放源代码的代码审查软件,使用网页界面.利用网页浏览器,同一个团队的软件程序员,可以相互审阅彼此修改后的程序代码,决定是否能够提交,退回或 ...

  3. ICG游戏:斐波那契博弈

    描述: 有一堆个数为n(n>=2)的石子,游戏双方轮流取石子,规则如下: 1)先手不能在第一次把所有的石子取完,至少取1颗: 2)之后每次可以取的石子数至少为1,至多为对手刚取的石子数的2倍: ...

  4. maven标签说明

    <project xmlns="http://maven.apache.org/POM/4.0.0 " xmlns:xsi="http://www.w3.org/2 ...

  5. C语言时间处理

    一.简介 时间处理在编程中经常遇到,包括程序的运行时间和显示时间等.在标准C中, 日期和时间的处理包含在 time.h 的头文件中,需要使用日期和时间相关的类型的函数的话, 需要导入time.h. 二 ...

  6. 企业招聘:UX设计师需要满足他们哪些期望?

    以下内容由Mockplus团队翻译整理,仅供学习交流,Mockplus是更快更简单的原型设计工具.   为了确定2017年最有价值的用户体验技能和特质,我特地参考了150多份工作要求.最后,得出了以下 ...

  7. IP多播技术及其应用

    随着全球互联网(Internet)的迅猛发展,上网人数正以几何级数快速增长,以因特网技术为主导的数据通信在通信业务总量中的比列迅速上升,因特网业务已成为多媒体通信业中发展最为迅速.竞争最为激烈的领域. ...

  8. Tomcat的windows10集群搭建(一台电脑同时运行多个tomcat配置方法)

    配置方法(好久不配置了,忘记了,今天还是总结下吧): 1.官网下载tomcat ,我下载了tomcat6.0和tomcat7.0(以便区分) 官网地址:http://tomcat.apache.org ...

  9. BZOJ 4326 NOIP2015 运输计划 (二分+树上差分)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1930  Solved: 1231[Submit][Statu ...

  10. Ubuntu的常识使用了解4

    寻找文件的「名称」 在Linux系统当中,文件的数量非常非常的多, 需要使用查找工具来高效查找指定文件位置: