hdu 2838 Cow Sorting 樹狀數組

hdu 2838


     《Cow Sorting》 這題本來興高采烈的想用java做一遍,結果做出來之後無限超內存,真是啊,做題的時候java這種東西還是輕易不要動了。還有感覺要把數字都要離散化的,結果後臺數據不需要離散化。


      題意:給一個n代表n個牛,然後再給n個數我覺得是n以內的數(包括n)。雖然體面上沒說。然後只能相鄰兩個數字交換位置,會讓牛產生怒氣值,值爲互相移動的兩個牛的編號值相加的和,求把牛按從小到大排好序之後最小讓牛產生的怒氣。


      思路:其實想要最小的怒氣值你只要不做無用功那不管怎麼移動都是最小值。 無用功即不把編號小的牛放到編號大的牛後面就行了。然後怒氣值就是(當前牛之前比當前牛編號大的牛的個數)*(當前牛的個數)+(當前牛之前比當前牛編號大的牛的編號總值),注意用long long。。


本題代碼

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;
#define ll long long
struct Node
{
    int qx;
    long long sum;
}C[100001];
int n;
int lowbit(int k)
{
    return k & (-k);
}
void add(int x, int val, int vall)
{
    while (x <= n)
    {
        C[x].qx += val;
        C[x].sum += vall;
        x += lowbit(x);
    }
}
ll queryqx(int x)
{
    ll sum1 = 0;
    while (x > 0)
    {
        sum1 += C[x].qx;
        x -= lowbit(x);
    }
    return sum1;
}
ll querysum(int x)
{
    ll sum2 = 0;
    while (x > 0)
    {
        sum2 += C[x].sum;
        x -= lowbit(x);
    }
    return sum2;
}
int main()
{
    while (scanf("%d", &n) == 1)
    {
        int cow;
        ll tqx, ans = 0, tsum;
        memset(C, 0, sizeof C);
        for (int i = 0; i < n; i++)
        {
            scanf("%d", &cow);
            add(cow, 1, cow);
            tqx = i+1-queryqx(cow);
            if (tqx > 0)
            {
                tsum = querysum(n) - querysum(cow);
                ans += tqx*cow + tsum;
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章