题目:

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

Source

题解:

同样的一道三维偏序题,将删除看成倒着插入,从而得出:<插入时间,位置,大小>(<t,a,b>),对于一个组数<t,a,b>,找寻(t>t1,a>a1且b<b1)的数量加到对应的ans[t]中,注意最后将ans叠加起来;

另外要注意在排完t后,a要正着排序求一遍ans然后倒着排序一遍ans,否则ans会少加(想想为什么单纯地求逆序对不用这样)

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int N=1e5+;
struct node
{
int t,a,b;
}q[N],temp[N];
int n,m,tree[N],to[N],tag[N],tim;
long long ans[N];
long long Ans;
inline int R()
{
char c;int f=;
for(c=getchar();c<''||c>'';c=getchar());
for(;c<=''&&c>='';c=getchar())
f=(f<<)+(f<<)+c-'';
return f;
}
inline bool cmp(node a,node b)
{
return a.t<b.t;
}
inline bool comp(node a,node b)
{
return a.a<b.a;
}
inline void insert(int u,int v)
{
for(int i=u;i<=n;i+=(i&(-i)))
if(tag[i]!=tim) tag[i]=tim,tree[i]=v;
else tree[i]+=v;
}
inline bool comp2(node a,node b)
{
return a.a>b.a;
}
inline int query(int u)
{
int temp=;
for(int i=u;i;i-=(i&(-i)))
if(tag[i]!=tim) continue;
else temp+=tree[i];
return temp;
}
inline void solve1(int l,int r)
{
if(l==r) return;
int mid=(l+r)/;
solve1(l,mid),solve1(mid+,r);
int i=l,j=mid+,k=l;tim++;
while(i<=mid&&j<=r)
{
if(comp(q[i],q[j]))
{
insert(q[i].b,);
temp[k++]=q[i++];
}
else
{
ans[q[j].t]+=query(n)-query(q[j].b);
temp[k++]=q[j++];
}
}
while(i<=mid) temp[k++]=q[i++];
while(j<=r)
{
ans[q[j].t]+=query(n)-query(q[j].b);
temp[k++]=q[j++];
}
for(j=l;j<=r;j++) q[j]=temp[j]; }
inline void solve2(int l,int r)
{
if(l==r) return;
int mid=(l+r)/;
solve2(l,mid),solve2(mid+,r);
int i=l,j=mid+,k=l;tim++;
while(i<=mid&&j<=r)
{
if(comp(q[j],q[i]))
{
insert(q[i].b,);
temp[k++]=q[i++];
}
else
{
ans[q[j].t]+=query(q[j].b);
temp[k++]=q[j++];
}
}
while(i<=mid) temp[k++]=q[i++];
while(j<=r)
{
ans[q[j].t]+=query(q[j].b);
temp[k++]=q[j++];
}
for(j=l;j<=r;j++) q[j]=temp[j];
}
int main()
{
#ifndef ONLINE_JUDGE
//freopen("a.in","r",stdin);
#endif
n=R(),m=R();
for(int i=;i<=n;i++)
{
q[i].a=i,q[i].b=R();
to[q[i].b]=i;
}
int Time=n,a;
for(int i=;i<=m;i++)
{
a=R();q[to[a]].t=Time--;
}
for(int i=;i<=n;i++)
if(!q[i].t) q[i].t=Time--;
sort(q+,q+n+,cmp);
solve1(,n);
sort(q+,q+n+,cmp);
solve2(,n);
for(int i=;i<=n;i++)
Ans+=ans[i];
for(int i=n;i>n-m;i--)
printf("%lld\n",Ans),Ans-=ans[i];
return ;
}

刷题总结——动态逆序对(bzoj3295)的更多相关文章

  1. 【CQOI2011】动态逆序对 BZOJ3295

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

  2. [bzoj3295][Cqoi2011]动态逆序对_主席树

    动态逆序对 bzoj-3295 Cqoi-2011 题目大意:题目链接. 注释:略. 想法:直接建立主席树. 由于是一个一个删除,所以我们先拿建立好的root[n]的权值线段树先把总逆序对求出来,接着 ...

  3. bzoj千题计划146:bzoj3295: [Cqoi2011]动态逆序对

    http://www.lydsy.com/JudgeOnline/problem.php?id=3295 正着删除看做倒着添加 对答案有贡献的数对满足以下3个条件: 出现时间:i<=j 权值大小 ...

  4. 【BZOJ3295】动态逆序对(线段树,树状数组)

    [BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...

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

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

  6. 2018.07.01 BZOJ3295: [Cqoi2011]动态逆序对(带修主席树)

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

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

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

  8. bzoj3295 [Cqoi2011]动态逆序对 cdq+树状数组

    [bzoj3295][Cqoi2011]动态逆序对 2014年6月17日4,7954 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数. ...

  9. bzoj3295 洛谷P3157、1393 动态逆序对——树套树

    题目:bzoj3295 https://www.lydsy.com/JudgeOnline/problem.php?id=3295 洛谷 P3157(同一道题) https://www.luogu.o ...

随机推荐

  1. mysql同步出现1062错误

    SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;slave start;show slave status \G执行多次,直到不会出现1062错误为止 或者: my.cnf s ...

  2. sql中保留2位小数

    问题: 数据库里的 float momey 类型,都会精确到多位小数.但有时候 我们不需要那么精确,例如,只精确到两位有效数字. 解决: 1. 使用 Round() 函数,如 Round(@num,2 ...

  3. Windwos下安装和使用MongoDB

    1)下载安装包下载路径:https://www.mongodb.com/download-center#community包名称:mongodb-win32-x86_64-3.4.10-signed. ...

  4. URAL 1519 Formula 1 (插头DP,常规)

    题意:给一个n*m的矩阵,格子中是'*'则是障碍格子,不允许进入,其他格子都是必走的格子,所走格子形成一条哈密顿回路,问有多少种走法? 思路: 本来是很基础的题,顿时不知道进入了哪个坑.这篇插头DP的 ...

  5. 聊聊C语言和ABAP

    这个公众号之前的文章,分享的都是Jerry和SAP成都研究院的同事在工作中学到的一些知识和感受.而今天这篇文章,写作的由来是因为最近我又参与了SAP成都数字创新空间应聘者的面试,和一些朋友聊了一些关于 ...

  6. JAVA初级必须要搞懂的事项(希望对新手有所帮助)

    1        安装JDK=> (1,下载JDK,安装,一般目录为C:\Program Files\Java中:2,通过Dos命令测试JDK是否安装=>java –version命令查看 ...

  7. MIPS——分支语句

    有关指令 li $t1,immediate #load immediate,立即数可正可负 la $t1,address #load address move $t1,$t2 #move $t2 to ...

  8. 屏蔽Alt+F4关闭窗体

    实现效果: 知识运用: KeyEventArgs类的Alt,Handled属性 public virtual bool Alt {get;} //获取一个值 该值指示是否曾按下Alt键 public ...

  9. Python基础篇 -- 列表

    3.2 列表的增删改查 ​ 列表使用 [] 来表示,列表中每个元素与元素之间用逗号隔开 ​ 列表也有索引和切片 # 切片切出来的也是列表 lst = ["梅西", "内马 ...

  10. shell脚本,awk 根据文件某列去重并且统计该列频次。

    a文件为 a a a s s d .怎么把a文件变为 a s d .怎么把a文件变为 a a a s s d 解题方法如下: 解题思路 [root@localhost study]# awk 'NR= ...