Cod sursa(job #2282125)

Utilizator razviii237Uzum Razvan razviii237 Data 13 noiembrie 2018 11:29:23
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.48 kb
#include <iostream>
#include <fstream>
#include <algorithm>

using namespace std;

const int maxn = 1e5+5, inf = 0x3f3f3f3f;

int aib[maxn], d[maxn], u[maxn], bk[maxn], n, i, v[maxn], lst[maxn], h, rez, irez, rz[maxn];

class InParser {
private:
	FILE *fin;
	char *buff;
	int sp;

	char read_ch() {
		++sp;
		if (sp == 4096) {
			sp = 0;
			fread(buff, 1, 4096, fin);
		}
		return buff[sp];
	}

public:
	InParser(const char* nume) {
		fin = fopen(nume, "r");
		buff = new char[4096]();
		sp = 4095;
	}

	InParser& operator >> (int &n) {
		char c;
		while (!isdigit(c = read_ch()) && c != '-');
		int sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		} else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}

	InParser& operator >> (long long &n) {
		char c;
		n = 0;
		while (!isdigit(c = read_ch()) && c != '-');
		long long sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		} else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}
};

// tin indicii in aib
void update(int pos, int ind)
{
    int x = pos;
    do
    {
        if(d[ind] > d[aib[x]]) {
            aib[x] = ind;
        }
        x += (x & (-x));
    }while(x <= n);
}

int query(int y)
{
    int x = y, mx = -inf, imx = 0;
    for(; x >= 1; x -= (x & (-x))) {
        if(d[aib[x]] >= mx) {
            mx = d[aib[x]];
            imx = aib[x];
        }
    }
    return imx;
}

InParser f("scmax.in");
ofstream g("scmax.out");

int main()
{
    f >> n;

    for(i = 1; i <= n; i ++) {
        f >> v[i];
        bk[i] = lst[i] = v[i];
    }

    sort(lst + 1, lst + n + 1);

    // scot dublurile
    h = 1;
    for(i = 2; i <= n; i ++) {
        if(lst[i] != lst[h]) {
            lst[++h] = lst[i];
        }
    }

    // nr mici
    for(i = 1; i <= n; i ++) {
        v[i] = lower_bound(lst + 1, lst + n + 1, v[i]) - lst;
    }

    // solve
    for(i = 1; i <= n; i ++) {
        u[i] = query(v[i]-1);
        d[i] = d[u[i]]+1;
        update(v[i], i);

        if(d[i] > rez) {
            rez = d[i];
            irez = i;
        }
    }

    // afisare
    int rr = rez;
    while(rr > 0)
    {
        rz[rr--] = bk[irez];
        irez = u[irez];
    }

    g << rez << '\n';
    for(i = 1; i <= rez; i ++) {
        g << rz[i] << ' ';
    }

    g.close();
    return 0;
}