# PBinfo #3729 – Exclusiv – Rezolvare C++

Sursa: Codul lui Andrei
Limbaj: C++
Autor rezolvare: deivid

## Enunț

Se consideră doi vectori care conțin numere naturale: s cu M elemente și v cu N elemente. Numim secvență i-exclusivă o secvență a vectorului s care nu conține niciuna dintre valorile v[1], v[2], …, v[i].

Cerința
Scrieți un program care să determine, pentru orice 1 ≤ i ≤ N, lungimea maximă a unei secvențe i-exclusive.

Date de intrare
Fișierul de intrare exclusiv.in conține pe prima linie numerele naturale M și N. Pe linia a doua se află M numere naturale reprezentând elementele vectorului s, iar pe linia a treia N numere naturale reprezentând elementele vectorului v. Valorile scrise pe aceeași linie sunt separate prin câte un spațiu.

Date de ieșire
Fișierul de ieșire exclusiv.out va conține N linii. Pe linia i (1 ≤ i ≤ N) va fi scris un număr natural care reprezintă lungimea maximă a unei secvențe i-exclusive.

Restricții și precizări

1 ≤ N ≤ 2.000
3 ≤ M ≤ 100.000
Vectorii s și v conțin numere naturale mai mici sau egale cu 2.000.000.000, memorate începând cu poziția 1
Valorile din fiecare vector nu sunt obligatoriu distincte două câte două.
O subsecvență nevidă în s este formată din elemente situate pe poziții consecutive (s[i], s[i + 1], …, s[j]), i ≤ j. O subsecvență i-exclusivă poate fi și vidă, lungimea ei fiind 0.

Exemplu:
exclusiv.in

20 6
11 5 11 7 2 10 11 9 2 77 88 88 88 2 7 2 2 77 2 11 
11 5 7 9 5 2
exclusiv.out

12
12
7
6
6
4
Explicație
Cea mai lungă secvență 1-exclusivă (care nu conține valoarea 11) este 9 2 77 88 88 88 2 7 2 2 77 2 și are lungimea 12.
Cea mai lungă secvență 2-exclusivă (care nu conține valorile 11 și 5) este 9 2 77 88 88 88 2 7 2 2 77 2 și are lungimea 12.
Cea mai lungă secvență 3-exclusivă (care nu conține valorile 11, 5 și 7) este 9 2 77 88 88 88 2 și are lungimea 7.
Cea mai lungă secvență 4-exclusivă (care nu conține valorile 11, 5, 7 și 9) este 2 77 88 88 88 2 și are
lungimea 6.
Cea mai lungă secvență 5-exclusivă (care nu conține valorile 11, 5 7, 9 și 5) este 2 77 88 88 88 2 și are lungimea 6.
Cea mai lungă secvență 6-exclusivă (care nu conține valorile 11, 5, 7, 9, 5 și 2) este 77 88 88 88 și are lungimea 4.

## Cod sursă C++

```cpp
/// m log n
#include <fstream>
#include <iostream>
#include <algorithm>
#define DIMN 2001
#define DIMM 300001
using namespace std;
int n, m, i, maxim, j, k;
int v[DIMN], s[DIMM];
pair<int, int> w[DIMN];
int L[DIMM];
int u[DIMM], a[DIMM], b[DIMM], R[DIMM];
int sol[DIMN];
int F[DIMN], SF[DIMN];
int main () {
    ifstream fin ("exclusiv.in");
    ofstream fout("exclusiv.out");
    fin>>m>>n;
    for (i=1;i<=m;i++)
        fin>>s[i];
    for (i=1;i<=n;i++) {
        fin>>v[i];
        w[i].first = v[i];
        w[i].second = i;
    }
    sort(w+1, w+n+1);
    for (i=1;i<=m;i++) {
        int st = 1;
        int dr = n;
        int mid;
        while (st <= dr) {
            mid = (st+dr)/2;
            if (w[mid].first < s[i])
                st = mid+1;
            else
                dr = mid-1;
        }
        if (st <= n  && w[st].first == s[i]) {
            F[w[st].second] ++;
            u[i] = 1;
        }
    }
    for (i= 1;i<=n;i++)
        SF[i] = SF[i-1] + F[i];
    for (i=m;i>=1;i--) {
        int st = 1;
        int dr = n;
        int mid;
        while (st <= dr) {
            mid = (st+dr)/2;
            if (w[mid].first < s[i])
                st = mid+1;
            else
                dr = mid-1;
        }
        if (st <= n  && w[st].first == s[i]) {
            R[SF[w[st].second]] = i;
            SF[w[st].second]--;
            L[ w[st].second ] = SF[w[st].second];
            u[i] = 1;
        }
    }
    int len = 0;
    u[0] = 1;
    u[m+1] = 1;
    for (i=1;i<=m+1;i++) {
        if(u[i] == 0)
            len++;
        else {
            if (u[i-1] == 0) {
                b[i-1] = len;
                a[i-len] = len;
            }
            len = 0;
        }
        if (len > maxim)
            maxim = len;
    }
    for (i=n;i>=1;i--) {
        sol[++k] = maxim;
        int ok = 1;
        for (j=1;j<i;j++)
            if (v[j] == v[i]) {
                ok = 0;
                break;
            }
        if (ok == 0)
            continue;
        int st = 1;
        int dr = n;
        int mid;
        while (st <= dr) {
            mid = (st+dr)/2;
            if (w[mid].first < v[i])
                st = mid+1;
            else
                dr = mid-1;
        }
        for (j=SF[w[st].second]+1;j<=SF[w[st].second]+F[w[st].second];j++) {
            int poz = R[j];
            if (u[poz] != 0) {
                u[poz] = 0;
                if (u[poz-1] != 0 && u[poz+1] != 0) {
                    a[poz] = 1;
                    b[poz] = 1;
                    len = 1;
                } else {
                    if (u[poz-1] == 0 && u[poz+1] != 0) {
                        b[poz] = b[poz-1]+1;
                        len = b[poz];
                        a[poz-b[poz]+1] = b[poz];
                    } else {
                        if (u[poz-1]!=0 && u[poz+1] == 0) {
                            a[poz] = a[poz+1]+1;
                            len = a[poz];
                            b[ poz + a[poz] - 1] = a[poz];
                        } else {
                            len = b[poz-1] + a[poz+1] + 1;
                            a[poz - b[poz-1]] = len;
                            b[poz + a[poz+1]] = len;
                        }
                    }
                }
                maxim = max(maxim, len);
            }
        }
    }
    for (i=k;i>=1;i--)
        fout<<sol[i]<<"\n";
    return 0;
}
```

## Resurse

- [Pagina originală](https://codulluiandrei.ro/rezolvari/pbinfo/3729)
- [Sursa C++](https://codulluiandrei.ro/rezolvari/pbinfo/3729/cod.cpp)
- [Sursa pe GitHub](https://raw.githubusercontent.com/codulluiandrei/pbinfo/main/pbinfo-3729/main.cpp)
- [Cursuri de informatică pentru BAC](https://codulluiandrei.ro/academia/info-curs/pachet-cpp/)
