zoukankan      html  css  js  c++  java
  • 咳咳,用树状数组求逆序对及例题

    关于树状数组,相信大家都已经比较熟悉了。。。
    那么,我们就先来砍一刀例题(嘻嘻)

    输入

    给出n以及n个数,求这其中的逆序对个数
    PS:逆序对,就是序列中ai>aj且i<j的有序对。
    输入:
    6
    5 4 2 6 3 1
    输出:
    11
    n<=5*10^5
    ai<=10^9

    嗯。。。
    这一题,很多人应该都会选择归并求逆序对吧。。。
    但是,树状数组求逆序对我们也应该要掌握掌握的说。
    那么,想让我们想一想,逆序对应该怎么快速求呢?
    我们可以倒着枚举。

    void add(int x) {for (;x<=n;x+=lowbit(x)) t[x]++;}
    
    int total(int x) {int s=0; for (;x>0;x-=lowbit(x)) s+=t[x]; return s;}
    
    for (int i=n;i>0;i--)
    	add(c[i]),ans+=total(c[i]-1);
    

    因为ai<=10^9,我们很容易就能想到离散化
    这个离散化呢,还要小心一点就是相等的情况。

    n=read();//read()为读入优化
    for (int i=1;i<=n;i++) a[i]=(node){read(),i};
    sort(a+1,a+n+1,cmp);c[a[1].num]=1;
    for (int i=2;i<=n;i++)
    {
    	if (a[i].val!=a[i-1].val) tot++;
    	c[a[i].num]=tot;
    }
    

    这样,我们就能简单而又容易地打出代码啦!

    #include<cstdio>
    #include<algorithm>
    #define ll long long
    #define lowbit(x) x&-x
    #define N 500010
    using namespace std;
    struct node{ll val,num;}a[N];
    ll ans=0,t[N]={0},c[N];int n,tot=1;
    
    inline int read()
    {
        int x=0,f=1; char c=getchar();
        while(c<'0' || c>'9') f=(c=='-') ? -1:f,c=getchar();
        while(c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    
    int cmp(node x,node y) {return x.val<y.val;}
    
    void add(int x) {for (;x<=n;x+=lowbit(x)) t[x]++;}
    
    ll total(int x) {ll s=0; for (;x>0;x-=lowbit(x)) s+=t[x]; return s;}
    
    int main()
    {
    //	freopen("nxd.in","r",stdin);
    //	freopen("nxd.out","w",stdout);
    	n=read();
    	for (int i=1;i<=n;i++) a[i]=(node){read(),i};
    	sort(a+1,a+n+1,cmp);c[a[1].num]=1;
    	for (int i=2;i<=n;i++)
    	{
    		if (a[i].val!=a[i-1].val) tot++;
    		c[a[i].num]=tot;
    	}
    	for (int i=n;i>0;i--)
    		add(c[i]),ans+=total(c[i]-1);
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    系统调用与库函数
    在树莓派上 搭建sqlite数据库
    (转)inux Read系统调用
    查看当前日期是这一年的第几天
    求解某个范围内的全部完数
    求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。
    输入三个整数x,y,z,请把这三个数据由大到小输出。
    模仿ArrayList底层实现
    可视化日历
    Oracle之约束条件1:主键约束
  • 原文地址:https://www.cnblogs.com/jz929/p/11817881.html
Copyright © 2011-2022 走看看