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
  • 相关阅读:
    Flume入门与进阶
    git如何忽略已经加入版本控制的文件
    Redis常用命令
    如何在宝塔面板上添加创建一个定时任务
    PHP代码篇(九)PHP接口开发如何使用JWT进行验证身份
    七. Go并发编程--sync.Once
    六. Go并发编程--WaitGroup
    5. Go 并发编程--sync/atomic
    4. Go并发编程--Mutex/RWMutex
    docker内服务访问宿主机服务
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/7946298.html
Copyright © 2011-2022 走看看