hdu5792

狗b題,氣死我了,思路正確,離散化的時候相同元素要按照位置從小到大排,然後不用兩遍求,手推一下,做減法就可以了~

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
#define ll long long
const int N = 50010;
vector<int>vec;
struct Node
{
    int val;
    int pos;
};

Node node[N];
int c[N], reflect[N],n;
long long a[N] ,b[N] , d[N],e[N],suma[N], sumb[N];
bool cmp(const Node& a, const Node& b)
{
    if(a.val == b.val) return a.pos < b.pos;
    return a.val < b.val;

}

int lowbit(int x)
{
    return x & (-x);
}

void update(int x)
{
    while (x <= n)
    {
        c[x] += 1;
        x += lowbit(x);
    }
}

int getsum(int x)
{
    int sum = 0;
    while (x > 0)
    {
        sum += c[x];
        x -= lowbit(x);
    }
    return sum;
}
int ni[N],ini[N],in[N];
ll aa[N], bb[N];
map<int,int>mp,mpp;
int main()
{
//  freopen("111.txt","r",stdin);
    while (scanf("%d", &n) != EOF)
    {
        mp.clear(); mpp.clear();
        for (int i = 1; i <= n; ++i) 
        {
            scanf("%d", &node[i].val);ini[i] = node[i].val;in[i] = node[i].val;
        //  num[node[i].val] ++;in
            node[i].pos = i;mpp[ini[i]] ++;
        }
        for(int i = 1 ; i <= n  ; i++){
            ni[i] = node[n - i + 1].val;
        }
        sort(node + 1, node + n + 1, cmp);   //排序 
        sort(ini + 1, ini + 1 + n);
        for (int i = 1; i <= n; ++i) {reflect[node[i].pos] = i; 
           int l = lower_bound(ini + 1 , ini + 1 + n, ini[i]) - ini;
           int r = upper_bound(ini + 1 , ini + 1 + n, ini[i]) - ini;
           suma[node[i].pos] = l - 1 ; sumb[node[i].pos] = n - r + 1;
        }  
        for (int i = 1; i <= n; ++i) c[i] = 0;   //初始化樹狀數組
        ll ans = 0;
        for (int i = 1; i <= n; ++i)
        {
            update(reflect[i]);
            int tmp = getsum(reflect[i]);
            d[i] = tmp - 1 - mp[in[i]];
            e[i] = i - tmp;
            a[i] = suma[i] - d[i] ;
            b[i] = sumb[i] - e[i] ;
            ans += i - tmp;
            mp[in[i]]++;
        }
        ll anss = 0 ;
        anss = 1ll * n * (n - 1) / 2  ;

        mp.clear();//vec.clear();
        for(int i = 1; i <= n ; i++){
            mp[ini[i]] ++;
        }
        map<int,int>::iterator it;
    //  cout <<" anss= " << anss <<endl;
        for(it = mp.begin() ; it != mp.end(); it ++){
            //cout << *it <<endl;
            int now = (*it).second;
            anss -= 1ll * (now * (now - 1)) / 2;
        }
        ans *= (anss - ans);
        for(int i = 1; i <= n ; i++){
            ans -= (b[i] + d[i]) * (a[i] + e[i]);
        }
        printf("%I64d\n", ans);
    } 
    return 0;
}
/*
4
99 18 101 23
9
1 1 2 2 2 2 1 1 1
6
1 1 2 2 2 2
20
1 1 2 2 2 2 1 1 1 1 1 2 1 1 1 1 1 2 2 2
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章