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
 
各种方法都可做
 
树套树(5.9s)
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std; int n,m,l,r,o,p,num=;
long long ans=;
inline int read(){
p=;o=getchar();
while(o<''||o>'') o=getchar();
while(o>=''&&o<='') p=p*+o-,o=getchar();
return p;
}
int root[],a[],tt[];
struct tree{
int l,r,k;
tree(){
k=;
}
};
tree t[];
inline void insert(int &p,int l,int r,int k){
if (p==) p=++num;
t[p].k++;
if (l==r) return;
int mid=l+r>>;
if (k<=mid) insert(t[p].l,l,mid,k);else insert(t[p].r,mid+,r,k);
}
inline void del(int p,int l,int r,int k){
t[p].k--;
if (l==r) return;
int mid=l+r>>;
if (k<=mid) del(t[p].l,l,mid,k);else del(t[p].r,mid+,r,k);
}
inline int qui(int p,int l,int r,int k){
if (p==) return ;
if (r==k) return t[p].k;
int mid=l+r>>;
if (k<=mid) return qui(t[p].l,l,mid,k);else return qui(t[p].r,mid+,r,k)+(t[p].l==?:t[t[p].l].k);
}
inline int qua(int p,int l,int r,int k){
if (p==) return ;
if (l==k) return t[p].k;
int mid=l+r>>;
if (k<=mid) return qua(t[p].l,l,mid,k)+(t[p].r==?:t[t[p].r].k);else return qua(t[p].r,mid+,r,k);
}
inline int lo(int x){return x&(-x);}
inline void in(int i,int k){
while(i<=n){
insert(root[i],,n,k);
i+=lo(i);
}
}
inline void de(int i,int k){
while(i<=n){
del(root[i],,n,k);
i+=lo(i);
}
}
inline long long ask(int x,int k){
long long s=;
k++;
while(x>){
if (k<=n) s+=qua(root[x],,n,k);
x-=lo(x);
}
return s;
}
inline long long aski(int x,int k){
long long s=;
k--;
while(x>){
if (k>=) s+=qui(root[x],,n,k);
x-=lo(x);
}
return s;
}
int main(){
register int i,j;
n=read();
m=read();
for (i=;i<=n;i++) in(i,a[i]=read()),tt[a[i]]=i;
for (i=;i<=n;i++) ans+=ask(i,a[i]);
while(m--){
printf("%lld\n",ans);
l=read();r=tt[l];
if (a[r]==) continue;a[r]=;
ans-=ask(r,l)+aski(n,l)-aski(r,l);
de(r,l);
}
}

CDQ分治

#include<cstdio>
#include<algorithm>
using namespace std;
int read_p,read_ca,pr_num,pr_ch[];
inline int read(){
read_p=;read_ca=getchar();
while(read_ca<''||read_ca>'') read_ca=getchar();
while(read_ca>=''&&read_ca<='') read_p=read_p*+read_ca-,read_ca=getchar();
return read_p;
}
inline void pr(long long k){
pr_num=;
while(k>) pr_ch[++pr_num]=k%,k/=;
while(pr_num)
putchar(pr_ch[pr_num--]+);
putchar('\n');
}
struct na{
int x,y,t;
}b[],o[],y[];
int n,m,u[],ti[],s[];
long long ans[][];
inline int low(int x){return x&(-x);} inline void add(int x){
while (x<=n){
s[x]++;
x+=low(x);
}
}
inline void del(int x){
while (x<=n){
s[x]--;
x+=low(x);
}
}
inline int ask(int x){
int ans=;
while (x>){
ans+=s[x];
x-=low(x);
}
return ans;
}
inline bool cmp(na a,na b){
if ((a.x==b.x)&&(a.y==b.y)) return a.t<b.t;
if (a.x==b.x) return a.y>b.y;
return a.x<b.x;
}
inline bool tmp(na a,na b){
if ((a.x==b.x)&&(a.y==b.y)) return a.t<b.t;
if (a.x==b.x) return a.y<b.y;
return a.x>b.x;
}
inline void work0(int l,int r){
if (l==r) return;
int mid=l+r>>,ll=l-,rr=mid;
for (register int i=l;i<=r;i++){
if (b[i].t<=mid) add(n-b[i].y+);
if (b[i].t>mid) ans[b[i].t][]+=ask(n-b[i].y+);
}
for (register int i=l;i<=r;i++)
if (b[i].t<=mid) o[++ll]=b[i];else o[++rr]=b[i];
for (register int i=l;i<=r;i++) b[i]=o[i];
for (register int i=l;i<=r;i++) if (b[i].t<=mid) del(n-b[i].y+);
work0(l,mid);work0(mid+,r);
}
inline void work1(int l,int r){
if (l==r) return;
int mid=l+r>>,ll=l-,rr=mid;
for (register int i=l;i<=r;i++){
if (y[i].t<=mid) add(y[i].y);
if (y[i].t>mid) ans[y[i].t][]+=ask(y[i].y);
}
for (register int i=l;i<=r;i++) if (y[i].t<=mid) del(y[i].y);
for (register int i=l;i<=r;i++)
if (y[i].t<=mid) o[++ll]=y[i];else o[++rr]=y[i];
for (register int i=l;i<=r;i++) y[i]=o[i];
work1(l,mid);work1(mid+,r);
}
int main(){
register int i,j=;
n=read();m=read();
for (i=;i<=n;i++) u[read()]=i;
for (i=;i<m;i++) ti[read()]=m-i;
for (i=;i<=n;i++){
if (ti[i]==) b[i].t=++j;else b[i].t=n-m+ti[i];
b[i].x=u[i];b[i].y=i;
y[i]=b[i];
}
sort(b+,b+n+,cmp);
sort(y+,y+n+,tmp);
work0(,n);work1(,n);
for (int i=;i<=n;i++) ans[i][]+=ans[i-][],ans[i][]+=ans[i-][];
for (int i=n;i>j;i--) pr(ans[i][]+ans[i][]);
}

bzoj 3295: [Cqoi2011]动态逆序对(树套树 or CDQ分治)的更多相关文章

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

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

  2. BZOJ 3295: [Cqoi2011]动态逆序对

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

  3. bzoj 3295 [Cqoi2011]动态逆序对(cdq分治,BIT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3295 [题意] n个元素依次删除m个元素,求删除元素之前序列有多少个逆序对. [思路] ...

  4. 【刷题】BZOJ 3295 [Cqoi2011]动态逆序对

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

  5. BZOJ 3295: [Cqoi2011]动态逆序对 [CDQ分治]

    RT 传送门 首先可以看成倒着插入,求逆序对数 每个数分配时间(注意每个数都要一个时间)$t$,$x$位置,$y$数值 $CDQ(l,r)$时归并排序$x$ 然后用$[l,mid]$的加入更新$[mi ...

  6. BZOJ 3295 [CQOI2011]动态逆序对 (三维偏序CDQ+树状数组)

    题目大意: 题面传送门 还是一道三维偏序题 每次操作都可以看成这样一个三元组 $<x,w,t>$ ,操作的位置,权值,修改时间 一开始的序列看成n次插入操作 我们先求出不删除时的逆序对总数 ...

  7. BZOJ 3295 [Cqoi2011]动态逆序对 ——CDQ分治

    时间.位置.数字为三个属性. 排序时间,CDQ位置,树状数组处理数字即可. #include <cstdio> #include <cstring> #include < ...

  8. 【Bzoj 3295】 动态逆序对(树套树|CDQ分治)

    [题意] 每次删除一个数,然后问删除前逆序对数. [分析] 没有AC不开心.. 我的树状数组套字母树,应该是爆空间的,空间复杂度O(nlogn^2)啊..哭.. 然后就没有然后了,别人家的树套树是树状 ...

  9. 【BZOJ】3295: [Cqoi2011]动态逆序对

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3295 mamaya,弱鸡xrdog终于会写树套树啦.... 将树状数组中每一个节点看成一棵 ...

随机推荐

  1. cell的复用机制

    以下全部都是转载自别人的博客:http://blog.sina.com.cn/s/blog_9c3c519b01016aqu.html 转自:http://www.2cto.com/kf/201207 ...

  2. android测试

    1.测试是否知道源代码: --黑盒测试 不知道代码 --白盒测试 知道源代码 2.按照测试粒度: --方法测试 --单元测试 Junit测试 --集成测试 --系统测试 3.按照测试暴力程度 --冒烟 ...

  3. 【知了堂学习笔记】_String、StringBuffer与StringBuilder的区别

    String Stringbuffer  StringBuilder的区别: 1.string是字符串常量,且长度是不可改变的,Stringbuffer.stringBuilder是字符串变量 2.S ...

  4. grep 与 find 简单命令

    在使用linux的时候,经常会用到查找文件或者查找文本,下面介绍两个命令. grep 使用方法: // 在当前目录下递归查找class字符串 grep "string" -r . ...

  5. go 1.9 Beta 1

    语言变化:增加了类型别名 To find out what has changed in Go 1.9, read the draft release notes: https://tip.golan ...

  6. 2018年第一篇行动笔记:Reading Log

    今天读了盖兆泉的文章<美国教师怎么上阅读课>,觉得干货颇多,不仅仅针对儿童英语阅读,而且对生活的方方面面都有助益. 该文章主要内容摘要如下: 学生需要大量时间阅读 这里的阅读时间是特指花在 ...

  7. ASP.NET Core使用静态文件、目录游览与MIME类型管理

    前言 今天我们来了解了解ASP.NET Core中的静态文件的处理方式. 以前我们寄宿在IIS中的时候,很多静态文件的过滤 和相关的安全措施 都已经帮我们处理好了. ASP.NET Core则不同,因 ...

  8. Transact-SQL参考--学习笔记

    基本的就不累赘了. 运算符 除法: dividend / divisor 如果用一个整数的 divisor 去除整数的 dividend,其结果是一个整数,小数部分被截断,如果要有小数可以将divid ...

  9. oracle PL/SQL语法基础

    目录 数据类型 定义变量 PL/SQL控制结构 参考资料 Oracle10g数据类型总结 PL/SQL之基础篇 数据类型 学习总结 字符类型 char.nchar.varchar.nvarchar:有 ...

  10. Hyperledger Fabric 本地运行的简单示例

    环境: Ubuntu 16.04 go 1.7.4 版本: Fabric v1.0.0-alpha 本文主要目的就是让大家体验以下Fabric网络环境搭建的具体过程,不基于集成化脚本手动搭建. 一.编 ...