Submission #1366279

#TimeUsernameProblemLanguageResultExecution timeMemory
1366279Sam_a17Financial Report (JOI21_financial)C++17
5 / 100
271 ms42700 KiB
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
//#include "temp.cpp"
#include <cstdio>
using namespace std;

#ifndef ONLINE_JUDGE
#define dbg(x)         \
    cerr << #x << " "; \
    print(x);          \
    cerr << endl;
#else
#define dbg(x)
#endif

#define sz(x)   (int)x.size()
#define len(x)  (int)x.length()
#define all(x)  (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define clr(x)  (x).clear()
#define uniq(x) x.resize(unique(all(x)) - x.begin());
#define blt     __builtin_popcount

#define pb   push_back
#define popf pop_front
#define popb pop_back
#define ld   long double
#define ll   long long

void print(long long t)
{
    cerr << t;
}

void print(int t)
{
    cerr << t;
}

void print(string t)
{
    cerr << t;
}

void print(char t)
{
    cerr << t;
}

void print(double t)
{
    cerr << t;
}

void print(long double t)
{
    cerr << t;
}

void print(unsigned long long t)
{
    cerr << t;
}

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
#define nl '\n'

// Indexed Set
template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template <class T, class V> void print(pair<T, V> p);
template <class T> void print(vector<T> v);
template <class T> void print(set<T> v);
template <class T, class V> void print(map<T, V> v);
template <class T> void print(multiset<T> v);

template <class T, class V> void print(T v[], V n)
{
    cerr << "[";
    for (int i = 0; i < n; i++)
    {
        print(v[i]);
        cerr << " ";
    }
    cerr << "]";
}

template <class T, class V> void print(pair<T, V> p)
{
    cerr << "{";
    print(p.first);
    cerr << ",";
    print(p.second);
    cerr << "}";
}

template <class T> void print(vector<T> v)
{
    cerr << "[ ";
    for (T i : v)
    {
        print(i);
        cerr << " ";
    }
    cerr << "]";
}

// template <class T> void print(vector <T> v) {cerr << "[ "; for (T i : v) {print(i); cerr << " ";} cerr << "]";}
template <class T> void print(set<T> v)
{
    cerr << "[ ";
    for (T i : v)
    {
        print(i);
        cerr << " ";
    }
    cerr << "]";
}

template <class T> void print(multiset<T> v)
{
    cerr << "[ ";
    for (T i : v)
    {
        print(i);
        cerr << " ";
    }
    cerr << "]";
}

template <class T> void print(Tree<T> v)
{
    cerr << "[ ";
    for (T i : v)
    {
        print(i);
        cerr << " ";
    }
    cerr << "]";
}

template <class T, class V> void print(map<T, V> v)
{
    cerr << "[ ";
    for (auto i : v)
    {
        print(i);
        cerr << " ";
    }
    cerr << "]";
}

template <class T> void print(deque<T> v)
{
    cerr << "[ ";
    for (T i : v)
    {
        print(i);
        cerr << " ";
    }
    cerr << "]";
}

// for random generations
mt19937 myrand(chrono::steady_clock::now().time_since_epoch().count());
// mt19937 myrand(131);

// for grid problems
int dx[8] = {-1, 0, 1, 0, 1, -1, 1, -1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

// lowest / (1 << 17) >= 1e5 / (1 << 18) >= 2e5 / (1 << 21) >= 1e6
void fastIO()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
}

// file in/out
void setIO(string str = "")
{
    fastIO();

    if (str == "input")
    {
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    }
    else if (str != "")
    {
        freopen((str + ".in").c_str(), "r", stdin);
        freopen((str + ".out").c_str(), "w", stdout);
    }
}

const int N = 3e5 + 10;

struct segTree
{
    vector<long long> tree;
    int size = 1;

    void init(int s)
    {
        while (size <= s)
        {
            size *= 2;
        }
        tree.assign(2 * size - 1, 0);
    }

    void upd(int u, int value, int x, int lx, int rx)
    {
        if (rx - lx == 1)
        {
            tree[x] = value;
            return;
        }

        int mid = (lx + rx) / 2;
        if (u < mid)
        {
            upd(u, value, 2 * x + 1, lx, mid);
        }
        else
        {
            upd(u, value, 2 * x + 2, mid, rx);
        }

        tree[x] = max(tree[2 * x + 1], tree[2 * x + 2]);
    }

    void upd(int u, int value)
    {
        upd(u, value, 0, 0, size);
    }

    void get(int u, int x, int lx, int rx)
    { // set value at pos u
        if (rx - lx == 1)
        {
            // dbg(tree[x])
            return;
        }

        int m = (lx + rx) / 2;
        if (u < m)
        {
            get(u, 2 * x + 1, lx, m);
        }
        else
        {
            get(u, 2 * x + 2, m, rx);
        }
        tree[x] = max(tree[2 * x + 1], tree[2 * x + 2]);
    }

    void get(int u)
    {
        get(u, 0, 0, size);
    }

    int find(int k, int l, int x, int lx, int rx)
    {
        if (tree[x] < k)
        {
            return -1;
        }
        if (rx <= l)
        {
            return -1;
        }

        if (rx - lx == 1)
        {
            return lx;
        }

        int mid = (lx + rx) / 2;
        int answ = find(k, l, 2 * x + 1, lx, mid);

        if (answ == -1)
        {
            answ = find(k, l, 2 * x + 2, mid, rx);
        }

        return answ;
    }

    int find(int k, int l)
    {
        return find(k, l, 0, 0, size);
    }
};

struct segTreeMax
{
    vector<long long> mTree;
    int size;

    void init(long long n)
    {
        size = 1;
        while (size < n)
        {
            size *= 2;
        }
        mTree.assign(2 * size - 1, 0);
    }

    void upd(int u, long long v, int x, int lx, int rx)
    { // set value at pos u
        if (rx - lx == 1)
        {
            mTree[x] = v;
            return;
        }

        int m = (lx + rx) / 2;
        if (u < m)
        {
            upd(u, v, 2 * x + 1, lx, m);
        }
        else
        {
            upd(u, v, 2 * x + 2, m, rx);
        }
        mTree[x] = max(mTree[2 * x + 1], mTree[2 * x + 2]);
    }

    void upd(int u, long long v)
    {
        upd(u, v, 0, 0, size);
    }

    long long qry(int l, int r, int x, int lx, int rx)
    { // range queries
        if (l >= rx || lx >= r)
        {
            return 0;
        }
        if (lx >= l && r >= rx)
        {
            return mTree[x];
        }

        int m = (rx + lx) / 2;
        long long s1 = qry(l, r, 2 * x + 1, lx, m);
        long long s2 = qry(l, r, 2 * x + 2, m, rx);
        return max(s1, s2);
    }

    long long qry(int l, int r)
    {
        return qry(l, r, 0, 0, size);
    }
};

segTreeMax seg_max;
segTree seg;

int a[N];
int n, d;

vector<int> adj[N];

int p[N], sz[N];
int l[N];

// dsu
void init()
{
    for (int i = 0; i < n; i++)
    {
        p[i] = i, sz[i] = 1;
        l[i] = i;
    }
}

int find(int a)
{
    if (a != p[a])
    {
        p[a] = find(p[a]);
    }
    return p[a];
}

int same(int a, int b)
{
    if (find(a) == find(b))
    {
        return 1;
    }
    return 0;
}

int merge(int a, int b)
{
    a = find(a), b = find(b);
    if (a == b)
    {
        return 0;
    }
    if (sz[b] > sz[a])
    {
        swap(a, b);
    }
    p[b] = a, sz[a] += sz[b];
    l[a] = min(l[a], l[b]);
    return 1;
}

void solve_()
{
    cin >> n >> d;

    vector<int> compress;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
        compress.push_back(a[i]);
    }

    sort(all(compress));
    uniq(compress);

    for (int i = 0; i < n; i++)
    {
        a[i] = lower_bound(all(compress), a[i]) - compress.begin() + 1;
        adj[a[i]].push_back(i);
    }

    init();
    seg.init(n + 10);
    seg_max.init(n + 10);
    vector<int> cons(n + 3), on(n + 1);
    vector<int> dp(n + 1);
    int answ = 0;
    for (int i = n; i >= 1; i--)
    {
        // dbg(adj[i])
        for (auto j : adj[i])
        {
            int max_ind = min(n, j + d);
            // if(max_ind == -1) {
            //   max_ind = n;
            // } else {
            //   // dbg(max_ind)
            //   seg.get(1);
            //   max_ind += d - 1;
            // }
            // dbg(max_ind)
            dp[j] = seg_max.qry(j, max_ind + 1) + 1;
            // dbg(dp[j])
            answ = max(answ, dp[j]);
            // dbg(dp[j])
            seg_max.upd(j, dp[j]);
            on[j] = true;
        }

        for (auto j : adj[i])
        {
            if (on[j + 1])
            {
                merge(j, j + 1);
                seg.upd(j + 1, 0);
            }

            if (j - 1 >= 0 && on[j - 1])
            {
                merge(j - 1, j);
            }

            int cur = find(j);
            // dbg(l[cur])
            // dbg(sz[cur])
            seg.upd(l[cur], sz[cur]);
        }
    }

    cout << answ << '\n';
}

int main()
{
    setIO();

    auto solve = [&](int test_case) -> void {
        for (int i = 1; i <= test_case; i++)
        {
            solve_();
        }
    };

    int test_cases = 1;
    // cin >> test_cases;
    solve(test_cases);

    return 0;
}

Compilation message (stderr)

Main.cpp: In function 'void setIO(std::string)':
Main.cpp:188:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  188 |         freopen("input.txt", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:189:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  189 |         freopen("output.txt", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:193:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  193 |         freopen((str + ".in").c_str(), "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:194:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  194 |         freopen((str + ".out").c_str(), "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...