zoukankan      html  css  js  c++  java
  • 树状数组求逆序对

    离散化(不去重)
    2 33423434 437834 25345 373 35  //将上面的数字换成下边的
    1    6       5      4    3   2
    之后再通过楼兰图腾中的思想求逆序对
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    typedef pair<int,int>PII;
    typedef long long ll;
    const int N=5e5+10;
    
    PII a[N];
    int b[N],c[N],n;
    
    int ask(int x)
    {
        int sum=0;
        for(;x>=1;x-=x&-x)
            sum+=c[x];
        return sum;
    }
    
    void add(int x,int k)
    {
        for(;x<=n;x+=x&-x)
            c[x]+=k;
    }
    
    int main()
    {
    //    freopen("P1908_11.in","r",stdin);
        cin>>n;
        ll sum=0;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i].first),a[i].second=i;
        sort(a+1,a+n+1);
        int cnt=0;
        a[0].first=-1;
        for(int i=1;i<=n;i++)
        {
            if(a[i].first==a[i-1].first)
                b[a[i].second]=cnt;
            else
            {
                b[a[i].second]=++cnt;
            }
        }
        //两种思路,倒序扫就是扫b[i]之后比b[i]小的数的个数
            for(int i=n;i>=1;i--)
    	{
    		sum+=ask(b[i]-1);
    		add(b[i],1);	
    	} 
        //正序扫就是求比b[i]之前比b[i]大的数的个数
        for(int i=1;i<=n;i++)
        {
            sum+=ask(n)-ask(b[i]);
            // cout<<cnt<<endl;
            add(b[i],1);
        }
        cout<<sum;
    }
    
  • 相关阅读:
    hdu4734 F(x)
    hdu2089 不要62 两解
    luogu2602 [ZJOI2010]数字计数 两解
    lemon
    UVA1218 完美的服务 Perfect Service
    luogu HNOI2003消防局的设立
    uva10891 game of sum
    uva10635 Prince and Princess
    UVA1394 And Then There Was One
    uva10003切木棍
  • 原文地址:https://www.cnblogs.com/forward-985/p/14370337.html
Copyright © 2011-2022 走看看