zoukankan      html  css  js  c++  java
  • P1908 逆序对(细节)(树状数组解法)

    求逆序对(树状数组)

    • 逆序对是什么呢?就是说在一个序列中,如果i<j但是(a_i>a_j)那么((a[i],a[j]))就是一个逆序对,是无序的。
    • 通俗的说,逆序对就是就是一个数与在它后面且比他小的数组成的数对。
    • 树状数组可以用来求逆序对,是利用它能求前缀/后缀和的原理
    • 将一个1~N的数组由后向前遍历,每次遍历到(a_i)时,在树状数组下标为(a_i)的地方+1,并向后一直到N维护前缀和,遍历到(a[i])时,求Q((a[i]-1))即(a[i])与其后面的数组成的逆序对个数
      (我写这道题主要是为了记一下离散化方法,因为洛谷上的例题用map会超时)

    Code

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int maxn=5e5+5;
    int t[maxn],a[maxn],n,tot;
    long long ans;
    inline long long rd(){
    	register int x=0,f=0;register char ch=getchar();
    	while(ch<'0'||ch>'9')f|=ch=='-',ch=getchar();
    	while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    	return f?-x:x;
    }
    void A(int x,int a){
    	for(;x<=n;x+=x&-x)t[x]+=a;
    }
    int Q(int x){
    	int ans=0;
    	for(;x;x-=x&-x)ans+=t[x];
    	return ans;
    }
    struct Node{
    	int id,data;
    }node[maxn];
    bool cmp(Node a,Node b){
    	return a.data<b.data;  
    }
    int main(){	
    //	freopen("1.in","r",stdin);
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i){
    		node[i].data=rd();
    		node[i].id=i;
    	}
    	sort(node+1,node+1+n,cmp);//离散化
    	for(int i=1;i<=n;++i){
    		if(node[i].data>node[i-1].data){//赋予其小点的数,我们只需要知道其相对位置即可
    			a[node[i].id]=i;
    		}else a[node[i].id]=a[node[i-1].id];//处理相等情况,离散化为一个数值
    	}
    	for(int i=n;i>=1;--i){
    		ans+=(long long)Q(a[i]-1);
    		A(a[i],1);
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    无锁并行框架构建复杂消费模型
    Disruptor框架EventProcessor和Workpool的使用
    .NET工作准备--04ASP.NET
    .NET工作准备--03进阶知识
    .NET工作准备--02基础知识
    .NET工作准备--01前言
    Java核心编程快速入门
    IntellijIDEA快速入门(Windows版)
    企业模式和设计模式快速入门
    架构设计深入学习02-概念架构与细化架构
  • 原文地址:https://www.cnblogs.com/Lour688/p/13229554.html
Copyright © 2011-2022 走看看