bzoj 3295 [Cqoi2011]动态逆序对(cdq分治,BIT)
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=3295
【题意】
n个元素依次删除m个元素,求删除元素之前序列有多少个逆序对。
【思路】
cdq分治
这个题转化一下可以变成刚刚做过的三维偏序。
首先有两个量:序 和 值,可以将样例写成
x 1
2 3 4 5
y 1 5
3 4 2
然后因为我们要删除一些东西,所以加上时间,则样例变为
t 1 2
3 4 5
x 3 5
4 1 2
y 3 2
4 1 5
删除顺序就是按照t从大到小。我们把它看作t从小到大的插入结点。
则我们要求的是,一个结点在t时刻插入,左边有多少个比它大,右边有多少个比它小,设这个点为(t0,x0,y0),则我们要求的就是满足
t<t0,x<x0,y>y0
t<t0,x>x0,y<y0
的点数。因为具体的值对结果并无影响我们可以通过把a改成n-a+1来改变符号的方向,具体就是求满足
t<t0,x<x0,y<(n-y0+1)
t<t0,x<(n-x0+1),y<y0
的点数。
于是问题变成了刚做过的
陌上花开 问题。
最后统计每个时间点发生之前产生的所有逆序对。
【代码】
#include<cstdio>
#include<iostream>
#include<algorithm>
#define rep(a,b,c) for(int a=b;a<=c;++a)
using namespace std; typedef long long ll;
const int N =*1e5+; void read(int &x) {
char c=getchar(); x=;
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*+c-'',c=getchar();
} struct Node {
int a,b,c,ans;
bool operator<(const Node& rhs) const {
return a<rhs.a;
}
}q[N],T[N];
bool cmp(const Node& x,const Node& y)
{
return x.b<y.b||(x.b==y.b&&x.c>y.c);
} int n,m,mx,C[N],rk[N];
ll ans[N]; void add(int x,int v)
{
for(;x<=mx;x+=x&-x) C[x]+=v;
}
int query(int x)
{
int res=;
for(;x;x-=x&-x) res+=C[x];
return res;
} void solve(int l,int r)
{
if(l==r) return ;
int mid=(l+r)>>;
solve(l,mid) , solve(mid+,r);
int l1=l,l2=mid+,i;
while(l2<=r) {
while(l1<=mid&&q[l1].b<q[l2].b) {
add(q[l1].c,);
l1++;
}
q[l2].ans+=query(q[l2].c);
l2++;
}
for(i=l;i<l1;i++) add(q[i].c,-);
l1=l,l2=mid+; int now=l;
while(l1<=mid||l2<=r) {
if(l2>r||l1<=mid&&cmp(q[l1],q[l2])) T[now++]=q[l1++];
else T[now++]=q[l2++];
}
for(int i=l;i<=r;i++) q[i]=T[i];
} int main()
{
read(n),read(m); mx=n+;
rep(i,,n) { q[i].b=i; read(q[i].c); }
int a;
rep(i,,m) { read(a); rk[a]=i; }
int sz=m;
rep(i,,n) if(!rk[i]) rk[i]=++sz;
rep(i,,n) q[i].a=n-rk[q[i].c]+;
sort(q+,q+n+);
rep(i,,n) q[i].b=n-q[i].b+;
solve(,n);
sort(q+,q+n+);
rep(i,,n) {
q[i].b=n-q[i].b+;
q[i].c=n-q[i].c+;
}
solve(,n);
rep(i,,n) ans[q[i].a]=q[i].ans;
rep(i,,n) ans[i]+=ans[i-];
for(int i=n;i>n-m;i--)
printf("%lld\n",ans[i]);
return ;
}
bzoj 3295 [Cqoi2011]动态逆序对(cdq分治,BIT)的更多相关文章
- BZOJ 3295: [Cqoi2011]动态逆序对 [CDQ分治]
RT 传送门 首先可以看成倒着插入,求逆序对数 每个数分配时间(注意每个数都要一个时间)$t$,$x$位置,$y$数值 $CDQ(l,r)$时归并排序$x$ 然后用$[l,mid]$的加入更新$[mi ...
- BZOJ 3295 [Cqoi2011]动态逆序对 ——CDQ分治
时间.位置.数字为三个属性. 排序时间,CDQ位置,树状数组处理数字即可. #include <cstdio> #include <cstring> #include < ...
- Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2886 Solved: 924[Submit][Stat ...
- [BZOJ3295][Cqoi2011]动态逆序对 CDQ分治&树套树
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j,且 ...
- bzoj3295: [Cqoi2011]动态逆序对(cdq分治+树状数组)
3295: [Cqoi2011]动态逆序对 题目:传送门 题解: 刚学完cdq分治,想起来之前有一道是树套树的题目可以用cdq分治来做...尝试一波 还是太弱了...想到了要做两次cdq...然后伏地 ...
- BZOJ3295 [Cqoi2011]动态逆序对 —— CDQ分治
题目链接:https://vjudge.net/problem/HYSBZ-3295 3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 1 ...
- BZOJ 3295: [Cqoi2011]动态逆序对
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3865 Solved: 1298[Submit][Sta ...
- 【BZOJ3295】[Cqoi2011]动态逆序对 cdq分治
[BZOJ3295][Cqoi2011]动态逆序对 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依 ...
- bzoj 3295: [Cqoi2011]动态逆序对(树套树 or CDQ分治)
Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计 ...
随机推荐
- [转载]Eziriz .NET Reactor 4.7.0.0 官方原版+破解补丁(强大的代码保护和软件防盗版工具)
Eziriz .NET Reactor 是一个强大的代码保护和软件防盗版工具,完全由.NET框架编写..NET Reactor支持NET平台的软件许可系统,并支持NET程序集所有语言.当.Net编译器 ...
- cf 283A
不能简单模拟(会超时) 运用一点小技巧 减少时间复杂度 #include <cstdio> #include <cstring> using namespace std; ...
- poj 2888 Magic Bracelet
经典的有限制条件的Burnside计数+矩阵乘法!!! 对于这种限制条件的情况我们可以通过矩阵连乘得到,先初始化矩阵array[i][j]为1.如果颜色a和颜色b不能涂在相邻的珠子, 那么array[ ...
- ANDROID_MARS学习笔记_S01_006ImageView
一.ImageView介绍 设置scalType Must be one of the following constant values. Constant Value Description ma ...
- C# 调用WebService的方法
很少用C#动态的去调用Web Service,一般都是通过添加引用的方式,这样的话是自动成了代理,那么动态代理调用就是我们通过代码去调用这个WSDL,然后自己去生成客户端代理.更多的内容可以看下面的两 ...
- linux page cache和buffer cache
主要区别是,buffer cache缓存元信息,page cache缓存文件数据 buffer 与 cache 是作为磁盘文件缓存(磁盘高速缓存disk cache)来使用,主要目的提高文件系统系性能 ...
- C中如何调用C++函数、类内函数 \混编\链接
在C中如何调用C++函数的问题,简单回答是将函数用extern "C"声明,当被问及如何将类内成员函数声明时,一时语塞,后来网上查了下,网上有一翻译C++之父的文章可以作为解答,遂 ...
- linux文件系统-基本磁盘2
直入主题-基本磁盘 硬盘数据按照不同特点和作用大致分为5部分:MBR区.DBR区.FAT区.DIR区和DATA区 1.MBR MBR(Main Boot Record 主引导记录区)位于整个硬盘的0磁 ...
- python学习笔记八--动态类型
一.变量,对象,引用: 1. 变量: 2. 对象:均包含了一个头部信息,有以下两部分内容 a.对象的数据类型, b.引用计数器:纪录当前引用货指向该对象的数量,一旦计数器被清零,该对象的内存空间就会被 ...
- 【HDOJ】4261 Estimation
挺不错的一道题,基本思路是dp.关键点是如何求区间内的Sigma|A_i-B_i|.线段树做TLE了,优先队列可以过. /* 4261 */ #include <iostream> #in ...