zoukankan      html  css  js  c++  java
  • 牛客练习赛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
    ",ans[1],ans[0]);
        else printf("%lld
    ",ans[0]);
        return 0;
    }
    /*******************
    3
    0 0 0
    *******************/
    View Code
  • 相关阅读:
    sqlserver中判断表或临时表是否存在
    Delphi 简单方法搜索定位TreeView项
    hdu 2010 水仙花数
    hdu 1061 Rightmost Digit
    hdu 2041 超级楼梯
    hdu 2012 素数判定
    hdu 1425 sort
    hdu 1071 The area
    hdu 1005 Number Sequence
    hdu 1021 Fibonacci Again
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/7946298.html
Copyright © 2011-2022 走看看