Cod sursa(job #3223910)

Utilizator Dragono63Stanciu Rares Stefan Dragono63 Data 14 aprilie 2024 09:51:54
Problema P-sir Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.1 kb
#ifndef LOCAL
    #pragma GCC optimize("O3")
    #pragma GCC target("avx2")
#endif

#ifdef LOCAL
    #define _GLIBCXX_DEBUG
#endif

#include <bits/stdc++.h>
#define pb push_back
#define pii pair<int, int>
using ll = long long;
using ci = const int;
using cll = const long long;

using namespace std;

const ll MOD = (1LL << 32);
const int NMAX = 2e3 + 5;
/*******************************/
// INPUT / OUTPUT

#ifndef LOCAL
    ifstream in("psir.in");
    ofstream out("psir.out");
    #define cin in
    #define cout out
#endif
/*******************************/
/// GLOBAL DECLARATIONS

int N;
int sol;
ll suma_ret;
int v[NMAX];

inline int aduna(int a, int b)
{
    suma_ret = (1LL * a + 1LL * b);
    if (suma_ret >= MOD) suma_ret -= MOD;

    return suma_ret; 
}

inline int diff(int a, int b)
{
    suma_ret = (1LL * a - 1LL * b);
    if (suma_ret < 0) suma_ret += MOD;

    return suma_ret;
}

struct AIB
{
    int n;
    vector <int> data;

    AIB(){}

    AIB(int _n)
    {
        n = _n;
        data.resize(n + 1, 0);
    }

    inline void update(int pos, int val)
    {
        while (pos <= n)
        {
            data[pos] = aduna(data[pos], val);
            pos += (pos & (-pos));
        }
    }

    inline int query(int pos)
    {
        int suma = 0;
        while (pos)
        {
            suma = aduna(suma, data[pos]);
            pos -= (pos & (-pos));
        }

        return suma;
    }
};

vector <int> valori;
vector <pii> updates[NMAX]; 
/*******************************/
/// FUNCTIONS

void ReadInput();
void Solution();
void Output();
/*******************************/
///-------------------------------------
inline void ReadInput()
{
    cin >> N;

    for (int i = 1 ; i <= N ; ++ i)
    {
        cin >> v[i];
        valori.push_back(v[i]);
    }
}
///-------------------------------------
inline int get_norm(int x)
{
    return lower_bound(valori.begin(), valori.end(), x) - valori.begin() + 1;
}
///-------------------------------------
inline void Solution()
{
    sort(valori.begin(), valori.end());
    valori.erase(unique(valori.begin(), valori.end()), valori.end());

    AIB aib_tmp = AIB(valori.size());
    int dp;
    for (int i = 1 ; i <= N ; ++ i)
    {
        aib_tmp = AIB(valori.size());
        for (auto up: updates[i])
            aib_tmp.update(up.first, up.second);

        updates[i].clear();
        for (int j = i + 1 ; j <= N ; ++ j)
        {
            dp = 1;
            if (v[i] > v[j])
            {
                dp = aduna(dp, aib_tmp.query(get_norm(v[j]) - 1));
            }
            else
            {
                if (v[i] < v[j])
                    dp = aduna(dp, diff(aib_tmp.query(valori.size()), aib_tmp.query(get_norm(v[j]))));
            }

            sol = aduna(sol, dp);            
            updates[j].push_back({get_norm(v[i]), dp});
        }
    }
}
///-------------------------------------
inline void Output()
{
    cout << sol;
}
///-------------------------------------
signed main()
{
    #ifndef LOCAL
        ios::sync_with_stdio(false);
        cin.tie(NULL);
        cout.tie(NULL);
    #endif
    ReadInput();
    Solution();
    Output();
    return 0;
}