Cod sursa(job #1059999)

Utilizator PsychoAlexAlexandru Buicescu PsychoAlex Data 17 decembrie 2013 13:43:44
Problema Deque Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 7.1 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <deque>
#include <unordered_map>

std::ifstream fin("deque.in");
std::ofstream fout("deque.out");

int n, siz;
struct nod
{
    int indice, val;
};


std::vector<nod> minHeapu;
std::vector<nod> maxHeapu;
std::unordered_map<int, int> minHashu;
std::unordered_map<int, int> maxHashu;
std::vector<int> moFoPos;
std::unordered_map<int, std::deque<int> > aparitii;

void swa(int &a, int &b)
{
    int aux = a;
    a = b;
    b = aux;
}




void insertuMaxu(nod val)
{
    aparitii[val.val].push_back(val.indice);
    if(aparitii[val.val].size() == 1)
    {
        maxHeapu.push_back(val);
        int i = maxHeapu.size() / 2;
        int j = maxHeapu.size() - 1;

        maxHashu[val.val] = j;

        while(i >= 1 && maxHeapu[i].val < val.val)
        {
            maxHashu[maxHeapu[i].val] = j;
            maxHashu[maxHeapu[j].val] = i;

            swa(maxHeapu[i].val, maxHeapu[j].val);
            swa(maxHeapu[i].indice, maxHeapu[j].indice);

            j = i;
            i = i / 2;
        }
    }
}

void deluMaxu(int position)
{
    int valInit = maxHeapu.back().val;
    position--;

    std::cout<<"sterg val: "<<moFoPos[position]<<"; pos: "<<maxHashu[moFoPos[position]]<<"; val in heap: "<<maxHeapu[maxHashu[moFoPos[position]]].val<<'\n';

    maxHeapu[maxHashu[moFoPos[position]]].val = maxHeapu.back().val;
    maxHeapu[maxHashu[moFoPos[position]]].indice = maxHeapu.back().indice;
    maxHashu[maxHeapu.back().val] = maxHashu[moFoPos[position]];

    maxHeapu.pop_back();

    int i = maxHashu[moFoPos[position]];
    while(i * 2 < maxHeapu.size())
    {
        int val = maxHeapu[i*2].val;
        int p = 0;

        if(i*2 + 1 < maxHeapu.size() && maxHeapu[i*2+1].val > maxHeapu[i*2].val)
        {
            val = maxHeapu[i*2+1].val;
            p = 1;
        }

        if(valInit < maxHeapu[i*2+p].val)
        {
            int a1 = maxHashu[maxHeapu[i].val], a2 = maxHashu[maxHeapu[i*2+p].val];

            maxHashu[maxHeapu[i].val] = a2;
            maxHashu[maxHeapu[i*2 + p].val] = a1;

            swa(maxHeapu[i].val, maxHeapu[i*2 + p].val);
            swa(maxHeapu[i].indice, maxHeapu[i*2 + p].indice);
        }
        else
        {
            break;
        }
        i = i * 2 + p;
    }
}





void insertuMinu(nod val)
{
    aparitii[val.val].push_back(val.indice);
    if(aparitii[val.val].size() == 1)
    {
        minHeapu.push_back(val);
        int i = minHeapu.size() / 2;
        int j = minHeapu.size() - 1;

        minHashu[val.val] = j;

        while(i >= 1 && minHeapu[i].val > val.val)
        {
            minHashu[minHeapu[i].val] = j;
            minHashu[minHeapu[j].val] = i;

            swa(minHeapu[i].val, minHeapu[j].val);
            swa(minHeapu[i].indice, minHeapu[j].indice);

            j = i;
            i = i / 2;
        }
    }
}

void deluMinu(int position)
{
    aparitii[moFoPos[position]].pop_front();
    if(aparitii[moFoPos[position]].size() == 0)
    {
        int valInit = minHeapu.back().val;
    //    position--;

//        std::cout<<"elem pos: "<<position<<"; valoarea: "<<moFoPos[position]<<"; in hash: "<<minHashu[moFoPos[position]]<<"; in heap: "<<minHeapu[minHashu[moFoPos[position]]].val<<'\n';

        minHeapu[minHashu[moFoPos[position]]].val = minHeapu.back().val;
        minHeapu[minHashu[moFoPos[position]]].indice = minHeapu.back().indice;
        minHashu[minHeapu.back().val] = minHashu[moFoPos[position]];

        minHeapu.pop_back();

        int i = minHashu[moFoPos[position]];
        while(i * 2 < minHeapu.size())
        {
            int val = minHeapu[i*2].val;
            int p = 0;

            if(i*2 + 1 < minHeapu.size() && minHeapu[i*2+1].val < minHeapu[i*2].val)
            {
                val = minHeapu[i*2+1].val;
                p = 1;
            }

            if(valInit > minHeapu[i*2+p].val)
            {
                int a1 = minHashu[minHeapu[i].val], a2 = minHashu[minHeapu[i*2+p].val];

                minHashu[minHeapu[i].val] = a2;
                minHashu[minHeapu[i*2 + p].val] = a1;

                swa(minHeapu[i].val, minHeapu[i*2 + p].val);
                swa(minHeapu[i].indice, minHeapu[i*2 + p].indice);
            }
            else
            {
                break;
            }
            i = i * 2 + p;
        }
    }
}

void citire()
{
//    std::deque<nod> moFoList;
    fin>>n>>siz;

    long long suma = 0;
    int p;
    for(int i = 0; i < n; i++)
    {
        fin>>p;

        moFoPos.push_back(p);
        nod elem;
        elem.indice = i;
        elem.val = p;

//        moFoList.push_back(elem);
        insertuMinu(elem);
//        insertuMaxu(elem);




//        std::cout<<"nr: "<<p<<'\n';
//
//        for(int i = 1; i < minHeapu.size(); i++)
//        {
//            std::cout<<minHeapu[i].val<<' ';
//        }
//        std::cout<<'\n';
//        for(int i = 1; i < maxHeapu.size(); i++)
//        {
//            std::cout<<maxHeapu[i].val<<' ';
//        }
//        std::cout<<'\n';


////        std::cout<<minHeapu[1].indice<<' '<<minHeapu[1].val<<":   ";
//        if(minHeapu[1].indice < i - siz + 1)
//        {
////            std::cout<<"delete indice    ";
//            deluMinu(1);
//            deluMaxu(maxHashu[minHeapu[1].val]);
////            minHeapu.pop_front();
//        }
//        while(maxHeapu.size() > 1 && maxHeapu[1].val > p)
//        {
//            std::cout<<"prea mare: "<<maxHeapu[1].val<<' '<<p<<'\n';
////            std::cout<<"delete prea mare    ";
//            deluMinu(minHashu[maxHeapu[1].val]);
//            deluMaxu(1);
////            moFoList.pop_back();
//        }

//        std::cout<<'\n';
//        for(int i = 1; i < minHeapu.size(); i++)
//        {
//            std::cout<<minHeapu[i].val<<' ';
//        }
//        std::cout<<'\n';
//        for(int i = 1; i < maxHeapu.size(); i++)
//        {
//            std::cout<<maxHeapu[i].val<<' ';
//        }
//        std::cout<<'\n';
//        std::cout<<'\n';

//        std::cout<<minHeapu[1].indice<<' '<<minHeapu[1].val<<'\n';

        if(i >= siz - 1)
        {
            suma += minHeapu[1].val;
//            std::cout<<i<<' '<<siz - 1<<": "<<minHeapu[1].indice<<' '<<minHeapu[1].val<<'\n';
//            std::cout<<minHashu[minHeapu[i-siz+1].val]<<'\n';
//            for(int i = 1; i < minHeapu.size(); i++)
//            {
//                std::cout<<minHeapu[i].val<<' ';
//            }
//            std::cout<<'\n';

            deluMinu(i-siz+1);

//            for(int i = 1; i < minHeapu.size(); i++)
//            {
//                std::cout<<minHeapu[i].val<<' ';
//            }
//            std::cout<<'\n';
//            std::cout<<'\n';
        }
    }
    fout<<suma<<'\n';
//    std::cout<<'\n'<<suma<<'\n';
}

int main()
{
    nod v;
    v.indice = -1;
    v.val = -1;
    minHeapu.push_back(v);
    maxHeapu.push_back(v);
//    moFoPos.push_back(-1);
    citire();
    return 0;
}