Cod sursa(job #1059993)

Utilizator PsychoAlexAlexandru Buicescu PsychoAlex Data 17 decembrie 2013 13:23:04
Problema Deque Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 6.5 kb
#include <iostream>
#include <fstream>
#include <vector>
#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;

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




void insertuMaxu(nod val)
{
    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)
{
    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)
{
    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+2);

//            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;
}