Cod sursa(job #2715511)

Utilizator beingsebiPopa Sebastian beingsebi Data 3 martie 2021 19:26:02
Problema Distincte Scor 35
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.77 kb
#include <bits/stdc++.h>
using namespace std;
ifstream f("distincte.in");
ofstream g("distincte.out");
typedef vector<int>::iterator vit;
class idkbro
{
    idkbro *left, *right;
    vector<int> freq;
    int lo, hi;

public:
    void build(vit st, vit dr, int x, int y)
    {
        this->lo = x;
        this->hi = y;
        //elementele intre [st,dr) sunt intre [x,y]
        if (x == y || st >= dr) //daca toate sunt egale sau daca secventa e vida ma opresc
            return;
        int mid = (x + y) / 2; //capatul secventelor fii
        auto check = [mid](int nr) {
            return nr <= mid;
        };
        freq.reserve(dr - st + 1);
        freq.push_back(0);
        for (vit it = st; it != dr; it++)
            freq.push_back(freq.back() + check(*it)); //retin pt fiecare i cate elemente din [1,i] trec in fiul stang
        vit pivot = stable_partition(st, dr, check);  //pun elementele fiului stang  pe primele pozitii si pe cele ale fiului drept pe urmataorele
        left = new idkbro;
        right = new idkbro;
        left->build(st, pivot, x, mid);
        right->build(pivot, dr, mid + 1, y);
    }
    int query(int x, int y)
    {
        if (x > y)
            return 0;
        if (lo == hi)
            return lo;
        int nleft = freq[y] - freq[x - 1];
        int lb = freq[x - 1];
        int rb = freq[y];
        return left->query(lb + 1, rb) + right->query(x - lb, y - rb);
    }
} idk;
int main()
{
    int n, m, vmax;
    vector<int> v;
    f >> n >> vmax >> m;
    v.resize(n + 1);
    for (int i = 1; i <= n; i++)
        f >> v[i];
    idk.build(v.begin() + 1, v.end(), 1, vmax);
    for (int x, y; m; m--)
    {
        f >> x >> y;
        g << idk.query(x, y) << '\n';
    }
    return 0;
}