码迷,mamicode.com
首页 > 其他好文 > 详细

楼兰图腾——逆序数

时间:2019-10-24 21:17:41      阅读:80      评论:0      收藏:0      [点我收藏+]

标签:printf   scanf   std   链接   +=   alt   col   wing   ret   

题目链接

题意:

在给定的序列中,可以构成多少个‘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\n",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\n",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\n",ans2,ans1);


    return 0;
}
View Code

 

楼兰图腾——逆序数

标签:printf   scanf   std   链接   +=   alt   col   wing   ret   

原文地址:https://www.cnblogs.com/j666/p/11734856.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!