zoukankan      html  css  js  c++  java
  • 珂朵莉的数列

    题目链接:https://ac.nowcoder.com/acm/problem/14522

    思路: 求区间内逆序对个数,可以找出逆序对之后求它对整个区间的贡献。 例如 j,k是一个逆序对,那么它对整个区间的贡献应该是(j-0)*(n-k+1),因此,用树状数组枚举k,找出(1~k-1)范围内大于a[k]的数的坐标和就行了。

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <stack>
    #include <queue>
    #include <cmath>
    #define ll long long
    #define pi 3.1415927
    #define inf 0x3f3f3f3f
    #define mod 1000000007
    using namespace std;
    ll n,m;
    ll a[1000005],b[1000005],c[1000005];
    ll lowbit(ll i)
    {
        return i&-i;
    }
    void add(ll i,ll p)  //这里是将坐标加上去,求前i项的坐标和
    {
        while (i<=n)
        {
            c[i]+=p;
            i+=lowbit(i);
        }
    }
    ll getsum(ll k)
    {
        ll res=0;
        while(k)
        {
            res+=c[k];
            k-=lowbit(k);
        }
        return res;
    }
    void Print(__int128_t x)  //__int128_t 输出方法
    {
        if(x==0)
            return ;
        Print(x/10);
        putchar(x%10+'0');
    }
    int main ()
    {
        ll T,i,t,j,k,p;
        cin>>n;
        for(i=1;i<=n;++i)
            scanf("%lld",&a[i]),b[i]=a[i];
        //先排序,之后二分,在a[i]中存的是第i个数的大小的位置
        sort(b+1,b+n+1);
        for(i=1;i<=n;++i)
            a[i]=lower_bound(b+1,b+n+1,a[i])-b;
        __int128_t sum=0;
        for(i=1;i<=n;++i)
        {
            sum+=(getsum(n)-getsum(a[i]))*(n-i+1);
            add(a[i],i);
        }
        if(sum==0)
            cout<<"0";
        else
            Print(sum);
        cout<<endl;
        return 0;
    }
  • 相关阅读:
    Python的简单介绍/解释器/变量/变量的数据类型/用户交互及流程控制(if)
    变量
    hello python
    页面默认值显示
    java 获取时间区间
    java Set 中 removeAll 与 addAll
    命名的数据库实例
    linux 打包与解包
    缓存工作原理
    java 格式化日期(转)
  • 原文地址:https://www.cnblogs.com/blowhail/p/13266593.html
Copyright © 2011-2022 走看看