牛客练习赛7E珂朵莉的数列

Posted walfy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客练习赛7E珂朵莉的数列相关的知识,希望对你有一定的参考价值。

题意:求所有子区间的逆序数对数之和

题解:线段树维护,对于每一对逆序数(l,r)属于l*(n-r+1)个区间,计算每一对对结果的贡献即可,可用树状数组维护,sum维护(n-r+1),按逆序数那样操作

这题最狗的地方是爆longlong,java又超时。。。,用了一个小技巧,避免爆longlong

技术分享图片
#include<bits/stdc++.h>
#define fi first
#define se second
#define ll long long
#define ull unsigned long long
#define mp make_pair
#define pb push_back
#define mod 1000000007
#define pii pair<int,int>
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
 
using namespace std;
 
const int g=10.0,eps=1e-9;
const int N=1000000+10,maxn=5000000+10,inf=0x3f3f3f3f;
 
ll a[N],b[N],sum[N];
void add(int i,ll x)
{
    while(i<N)
    {
        sum[i]+=x;
        i+=i&(-i);
    }
}
ll query(int i)
{
    ll ans=0;
    while(i>0)
    {
        ans+=sum[i];
        i-=i&(-i);
    }
    return ans;
}
int main()
{
    /*ios::sync_with_stdio(false);
    cin.tie(0);*/
    ll n,cnt=0;
    scanf("%lld",&n);
    for(ll i=1;i<=n;i++)scanf("%lld",&a[i]),b[cnt++]=a[i];
    sort(b,b+cnt);
    cnt=unique(b,b+cnt)-b;
    for(ll i=1;i<=n;i++)a[i]=lower_bound(b,b+n,a[i])-b,a[i]++;
    ll ans[2]={0},te=1e18;
    for(ll i=1;i<=n;i++)
    {
        ans[0]+=(ll)(n-i+1)*(query(n)-query(a[i]));
        if(ans[0]>=te)ans[1]+=ans[0]/te,ans[0]%=te;
        add(a[i],i);
    }
    if(ans[1])printf("%lld%018lld\n",ans[1],ans[0]);
    else printf("%lld\n",ans[0]);
    return 0;
}
/*******************
3
0 0 0
*******************/
View Code

 

以上是关于牛客练习赛7E珂朵莉的数列的主要内容,如果未能解决你的问题,请参考以下文章

牛客练习赛7 E珂朵莉的数列(树状数组+爆long long解决方法)

牛客练习赛9 F - 珂朵莉的约数

牛客练习赛9 B - 珂朵莉的值域连续段

NC14522珂朵莉的数列(考虑贡献)

51NOD 2368 珂朵莉的旅行

牛客网 珂朵莉与宇宙(思维)