楼兰图腾——逆序数

Posted j666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了楼兰图腾——逆序数相关的知识,希望对你有一定的参考价值。

题目链接

题意:

在给定的序列中,可以构成多少个‘v’ 和 ‘^’

题解:

‘v‘的解法

由于序列中的数是从小到大给出的,所以我们如果知道a[i]的前面有多少个比他大的数a[i]的后面有多少个比他大的数,那么可以构成的V就是这两个数之积,而最终答案ans就是所有位置积的累加

同理’^‘的解法同理

代码:

技术图片
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
ll n,m;
ll c[maxn],a[maxn];
ll ldown[maxn],rdown[maxn],lup[maxn],rup[maxn];
void update(ll pos,ll x)
{
    for(ll i=pos;i<=n;i+=i&-i)c[i]+=x;
}
ll query(ll pos)
{
    ll ans=0;
    for(ll i=pos;i;i-=i&-i)ans+=c[i];
    return ans;
}
int main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
    }
    for(int i=1;i<=n;i++)
    {
        update(a[i],1);
        ldown[i]=query(a[i]-1);
    }
    memset(c,0,sizeof c);
    for(int i=n;i>0;i--)
    {
        update(a[i],1);
        rdown[i]=query(a[i]-1);
    }
    memset(c,0,sizeof c);
    for(int i=1;i<=n;i++)
    {
        update(a[i],1);
        lup[i]=i-query(a[i]);
       // printf("%d==%d
",i,lup[i]);
    }
    memset(c,0,sizeof c);
    for(int i=n;i>0;i--)
    {
        update(a[i],1);
        rup[i]=(n-i+1)-query(a[i]);
        //printf("%d==%d
",i,rup[i]);
    }
    ll ans1=0;
    for(int i=1;i<=n;i++)ans1+=ldown[i]*rdown[i];
    ll ans2=0;
    for(int i=1;i<=n;i++)ans2+=lup[i]*rup[i];
    printf("%lld %lld
",ans2,ans1);


    return 0;
}
View Code

 

以上是关于楼兰图腾——逆序数的主要内容,如果未能解决你的问题,请参考以下文章

CH4201楼兰图腾

楼兰图腾 题解

楼兰图腾(树状数组)

楼兰图腾(权值线段树)

241. 楼兰图腾树状数组

tyvj 1432 楼兰图腾