动态逆序对 CDQ分治

传送门:https://www.luogu.org/problemnew/show/P3157

题意:

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

题解:

这个题是告诉你如何将一个问题转换为三维偏序问题

首先,求解逆序对,那么a.val>b.val,删除一个元素的时间是t,a.t<b.t,这个元素对应的原序列中的位置为pos,那么a.pos<b.pos,这样我们就可以转换为一个三维偏序的问题

对于这个三维偏序问题,我们就可以采用cdq分治给解决,逆序对的统计可以套一个树状数组解决

代码:

#include <set>
#include <map>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
int lowbit(int x) {
return x & (-x);
}
int bit[maxn];
void add(int pos, int val) {
while(pos < maxn) {
bit[pos] += val;
pos += lowbit(pos);
}
}
int sum(int pos) {
int res = 0;
while(pos) {
res += bit[pos];
pos -= lowbit(pos);
}
return res;
}
int n, m;
struct node {
int m, v, d, id, t;
} a[maxn];
LL ans[maxn];
bool cmpd(node a, node b) {
return a.d < b.d;
}
void CDQ(int l, int r) {
if(l == r) return;
int mid = (l + r) >> 1;
CDQ(l, mid);
CDQ(mid + 1, r);
sort(a + l, a + mid + 1, cmpd);
sort(a + mid + 1, a + r + 1, cmpd);
int j = l;
for(int i = mid + 1; i <= r; ++i) {
while(j <= mid && a[j].d <= a[i].d) {
add(a[j].v, a[j].m);
j++;
}
ans[a[i].id] += a[i].m * (sum(n) - sum(a[i].v));
}
for(int i = l; i < j; i++) {
add(a[i].v, -a[i].m);
}
j = mid;
for(int i = r; i > mid; i--) {
while(j >= l && a[j].d >= a[i].d) {
add(a[j].v, a[j].m);
j--;
}
ans[a[i].id] += a[i].m * sum(a[i].v - 1);
}
for(int i = mid; i > j; i--) {
add(a[i].v, -a[i].m);
}
}
int match[maxn];
int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
scanf("%d%d", &n, &m);
int tot = 0;
for(int i = 1, x; i <= n; i++) {
scanf("%d", &x);
match[x] = i;
a[++tot].m = 1;
a[tot].v = x;
a[tot].d = i;
a[tot].id = 0;
a[tot].t = tot;
}
for(int i = 1, x; i <= m; i++) {
scanf("%d", &x);
a[++tot].m = -1;
a[tot].v = x;
a[tot].d = match[x];
a[tot].id = i;
a[tot].t = tot;
}
CDQ(1, tot);
for(int i = 1; i <= m; i++) {
ans[i] += ans[i - 1];
}
for(int i = 0; i < m; i++) {
printf("%lld\n", ans[i]);
} return 0;
}

P3157 动态逆序对 CDQ分治的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

    一道CDQ分治模板题简单来说,这道题是三维数点对于离线的二维数点,我们再熟悉不过:利用坐标的单调递增性,先按更坐标排序,再按纵坐标排序更新和查询时都直接调用纵坐标.实际上,我们是通过排序将二维中的一维 ...

  8. LUOGU P3157 [CQOI2011]动态逆序对(CDQ 分治)

    传送门 解题思路 cdq分治,将位置看做一维,修改时间看做一维,权值看做一维,然后就转化成了三维偏序,用排序+cdq+树状数组.注意算删除贡献时要做两次cdq,分别算对前面和后面的贡献. #inclu ...

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

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

随机推荐

  1. PLAY2.6-SCALA(七) Streaming HTTP response

    1.从HTTP1.1开始,服务端为了在single connection下对HTTP请求及响应提供服务,需要在response中提供响应的Content-Length. 默认情况下,不需要显示的指明C ...

  2. Maximum Depth of Binary Tree 树的最大深度

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  3. hdu1536 sg打表

    标记数组用bool型防止超时.输入的f[ ]要排序. #include<stdio.h> #include<string.h> #include<algorithm> ...

  4. 寒哥教你学iOS - 经验漫谈

    http://www.jianshu.com/p/cb54054d3add 寒哥教你学iOS - 经验漫谈 字数2848 阅读1896 评论19 喜欢43 顺便来个广告 iOS开发者 群1734993 ...

  5. 【NS2】How to remove Cygwin completely from Windows

    How to remove Cygwin completely from Windows 9th September 2012. 31243 views. Software Remember need ...

  6. TextView.setTextColor(int); 括号里那个颜色int值的理解

    原本以为是R.id里的东西,后来发现不是 http://dianhua1990627.blog.163.com/blog/static/2755558820132262150387/

  7. 详解TableStore模糊查询——以订单场景为例

    背景 订单系统在各行各业中广泛应用,为消费者.商家后台.促销系统等第三方提供用户.产品.订单等多维度的管理和查询服务.为了挖掘出海量订单数据的潜能,丰富高效的查询必不可少.然而很多时候并不能给出完整准 ...

  8. DTCC 2019 | 深度解码阿里数据库实现 数据库内核——基于HLC的分布式事务实现深度剖析

    摘要:分布式事务是分布式数据库最难攻克的技术之一,分布式事务为分布式数据库提供一致性数据访问的支持,保证全局读写原子性和隔离性,提供一体化分布式数据库的用户体验.本文主要分享分布式数据库中的时钟解决方 ...

  9. vue项目配置同一局域网可使用ip访问

    1.检查 package.json文件,scripts.dev设置 host改成 "0.0.0.0" 2.config文件中找到 index.js 文件的host改成 " ...

  10. EL表达式中的empty和null

    EL表达式中的empty和null 先说一下EL表达式中的null和empty区别,然后再说说最近在项目中出现的一个有趣的问题. EL中的null和empty都可用来判断值是否为空,但两者存在略微的区 ...