P1908 逆序对-(树状数组)

https://www.luogu.org/problem/P1908

比较喜欢线段树,懒得用树状数组(只会套模板,位运算的精髓没有领悟到),一直没有记录树状数组代码,又得捡回来,趁这道题记录一下模板,为三维偏序cdq套树状数组铺垫一下。

解题思路:先对原数组a从大到小排序,依次添加进树状数组c里,每次求前缀和的结果就是 当前数的逆序对的个数。

例如数据:55,44,22,66,33,11

初始化树状数组c,清0;

添加66到4号位,则添加数组为 0,0,0,1,0,0; 66前没有比它大的数,逆序对个数为0,树状数组C为0,0,0,1,0,0;

添加55到1号位,则添加数组为 1,0,0,1,0,0; 55前没有比它大的数,逆序对个数为0,树状数组C为1,1,0,2,0,0;

添加44到2号位,则添加数组为 1,1,0,1,0,0; 44前有55比它大,逆序对个数为1,树状数组C为1,2,0,3,0,0

添加33到5号位,则添加数组为 1,1,0,1,1,0; 33前有55,44,66比它大,逆序对个数为3,树状数组C为1,2,0,3,1,1

添加22到3号位,则添加数组为 1,1,1,1,1,0; 22前有55,44,66比它大,逆序对个数为2,树状数组C为1,2,1,4,1,2

添加11到6号位,则添加数组为 1,1,1,1,1,1; 11前有55,44,22,66,33比它大,逆序对个数为5,树状数组C为1,2,1,4,1,2

坑:如果有相同的数,则排序时按照后面的先添加,这样就不会重复计算逆序对。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<ctime>
#define ll long long
#define inf 0x3f3f3f3f
const double pi=3.1415926;
using namespace std;

const int maxx=500005;
struct node
{
    int id;
    int val;
};
node a[maxx];///原数组
int c[maxx];///树状数组
int n;

bool cmp(node p1,node p2)
{
    if(p1.val==p2.val)///坑
        return p1.id>p2.id;
    return p1.val>p2.val;
}

int lowbit(int x)
{
    return x&(-x);
}

void add(int x,int val)///在x的位置添加val值
{
    while(x<=n+1)///x需要小于32005,否则,那些输入x=20000的大数据没办法找到左下的行星数量
    {
        c[x]+=val;
        x+=lowbit(x);
    }
}

int sum(int x)
{
    int res=0;
    while(x>0)
    {
        res+=c[x];
        x-=lowbit(x);
    }
    return res;
}

int main()///P1908
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i].val),a[i].id=i;
    sort(a+1,a+n+1,cmp);
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        ans +=(ll)sum(a[i].id);
        add(a[i].id,1);
    }
    printf("%lld\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/shoulinniao/p/11619715.html

时间: 2024-10-21 03:17:04

P1908 逆序对-(树状数组)的相关文章

luogu P1908 逆序对 |树状数组

题目描述 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计.最近,TOM老猫查阅到一个人类称之为"逆序对"的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中ai>aj且i<j的有序对.知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目. Update:数据已加强. 输入格式 第一行,一个数n,表示序列中有n个数. 第二行n个数,表示给定的序列.序列中每个数字不超过10

BZOJ3295 CQOI2011 动态逆序对 树状数组套线段树

离线倒着做,每次加入一个节点后新增的逆序对数量就是其左边大于它的数的个数(左边数的总数-左边小于它的数的个数)+右边小于它的数的个数 用树状数组维护求和,对于树状数组中每个节点v所对应的区间线段树维护区间[l,r]中大于v的数的个数. 最后唯一的问题就是指针版线段树MLE-- #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <alg

求逆序对[树状数组] jdoj

求逆序对 题目大意:给你一个序列,求逆序对个数. 注释:n<=$10^5$. 此题显然可以跑暴力.想枚举1到n,再求在i的后缀中有多少比i小的,统计答案即可.这显然是$n^2$的.这...显然过不去,我们思考如何优化?显然,这里的有些过程是重复的.我们将这个序列设为a序列,对于两个1到n中的整数i<j,在j后面的数我们进行了多次重复枚举,我们思考如何优化.容易想到用一个桶来记录.只需要记录对于每一个数来讲,我后面有多少个数是比我小的,只需要将桶中的数累加即可.但是,我们必须记录是这个数之后的桶

【2018.12.15】【考试总结】【模拟+逆序对+树状数组+贪心+multiset】爆零之旅

这是我悲惨的接近爆零的一次考试,但是本蒟蒻不能放弃,还是要总结的QAQ 答题卡 [题目背景] 八月是个悲惨的月份.先不谈炎热的天气,对于新生来说,八月意味着军训: 而对于高二高三的同学来说,八月意味着开学考试.而考试就意味着改卷,改卷 也就意味着答题卡.不幸的是,学校读答题卡的机器的评分软件坏了,wyx 就被 老师要求写一个评分的程序. [问题描述] 软件需要读入学生的姓名.试题答案以及学生的答题卡信息. 学生姓名 学校的信息管理系统中存储了所有学生的姓名,一共 名学生.每个学生的 名字的组成只

POJ - 2299 - Ultra-QuickSort = 归并排序 + 逆序对 / 树状数组

http://poj.org/problem?id=2299 求逆序对最简单的绝对不会是树状数组,一定是归并排序(认真),不过树状数组会不会快一点呢?理论上应该是树状数组快一点(假如不进行离散化). #include<algorithm> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<map> #include<set

BZOJ 3295 [Cqoi2011]动态逆序对 树状数组套线段树

题意:链接 方法:树状数组套线段树 解析: 这题基本上写的都是什么CDQ点分治,主席树之类的,然而这我都并不会,所以写了一发平衡树套线段树想卡时卡过去,然而我并没有得逞,T的不要不要的,这里用平衡树套线段树的方法参见我的题解:排队.这道题比那道更要简单. 然后我就打算弃坑了~不过看140142做这道题做的热火朝天的,还是打算回来做一下,yy下树状数组套线段树,然后去看hz的题解,只看懂他写理论部分了,代码部分不知所云,所以还是还是得yy.引用理论部分. 删除某个数,只要统计它之前还存在的比它大的

POJ_3067 Japan[ 逆序数 树状数组 or 归并排序)

传送门:POJ_3067 题目:n,m,k;左右两列数,数的范围分别1-n,1-m,然给k个连线. Sample Input 1 3 4 4 1 4 2 3 3 2 3 1 Sample Output Test case 1: 5 思路:逆序数 代码: //树状数组版 //块状数组 #include<iostream> #include<cstring> #include<cmath> #include<cstdio> #include<algorit

HPU1291 小朋友排队 【逆序数+树状数组】

1291: 小朋友排队 时间限制: 1 Sec  内存限制: 128 MB 提交: 2  解决: 1 [提交][状态][讨论版] [Edit] 题目描述 n 个小朋友站成一排.现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友. 每个小朋友都有一个不高兴的程度.开始的时候,所有小朋友的不高兴程度都是0. 如果某个小朋友第一次被要求交换,则他的不高兴程度增加1,如果第二次要求他交换,则他的不高兴程度增加2(即不高兴程度为3),依次类推.当要求某个小朋友第k次交换时,他的不高

hdu 1394 Minimum Inversion Number 逆序数/树状数组

Minimum Inversion Number Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1394 Description The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai

POJ 2299 Ultra-QuickSort(逆序数 树状数组)

Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 45960   Accepted: 16702 Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swappin