zoukankan      html  css  js  c++  java
  • 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)
        {
            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
    ",ans);
        return 0;
    }
  • 相关阅读:
    两个半成品的ORM
    Mayberry小镇的管理 | 三种截然不同的领导风格 3M
    敏捷的目的(方向)错了以后……
    Error:java: Compilation failed: internal java compiler error
    java: -source 1.5 中不支持 diamond 运算符 (请使用 -source 7 或更高版本以启用 diamond 运算符)
    看mybatis日志模块时涉及的动态代理
    看的顺眼的却Destination Unreachable
    如何下载钉钉回放视频
    不想学习时看一看会有帮助的,“但行好事,莫问前程”
    守护线程
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/11619715.html
Copyright © 2011-2022 走看看