Cod sursa(job #2734552)

Utilizator FischerMiguel Mini Fischer Data 1 aprilie 2021 08:27:19
Problema Coduri Huffman Scor 100
Compilator cpp-32 Status done
Runda Arhiva educationala Marime 3.35 kb
#include<bits/stdc++.h>
	
using namespace std;
	
 
	
const int maxN=(1e6)+5;
	
 
	
 
	
deque<pair<int,int> > q,q2;
	
//vector<pair<int,pair<int,long long> > > sol;
	
pair<int,long long> sol[maxN];
	
 
	
 
	
bool cmp(pair<int,pair<int,int> > a,pair<int,pair<int,int> > b)
	
{
	
    return a.second.second<b.second.second;
	
}
	
 
	
int g[maxN][2],n;
	
 
	
int frecv[maxN];
	
 
	
long long ans=0;
	
 
	
void dfs(int node,int len,long long code)
	
{
	
    if(node<=n)
	
    {
	
        sol[node]=make_pair(len,code);
	
        ans=ans+1LL*frecv[node]*len;
	
 
	
        return;
	
    }
	
    dfs(g[node-n][0],len+1,code*2LL);
	
    dfs(g[node-n][1],len+1,code*2LL+1LL);
	
 
	
}
	
 
	
char buff[100005];
	
const int dim=(1e5);
	
int pos=0;
	
 
	
void read(int &nr)
	
{
	
    nr=0;
	
    while(!isdigit(buff[pos]))
	
    {
	
        pos++;
	
        if(pos==dim)
	
        {
	
            pos=0;
	
            fread(buff,1,dim,stdin);
	
        }
	
    }
	
 
	
    while(isdigit(buff[pos]))
	
    {
	
        nr=nr*10+buff[pos]-'0';
	
        pos++;
	
        if(pos==dim)
	
        {
	
            pos=0;
	
            fread(buff,1,dim,stdin);
	
        }
	
    }
	
}
	
pair<int,pair<int,int> > vect[5];
	
int main()
	
{
	
    freopen("huffman.in","r",stdin);
	
    freopen("huffman.out","w",stdout);
	
 
	
 
	
    fread(buff,1,dim,stdin);
	
 
	
    read(n);
	
 
	
 
	
    for(int i=1;i<=n;i++)
	
    {
	
        int x;
	
        //scanf("%d",&x);
	
        read(x);
	
 
	
        frecv[i]=x;
	
        q.push_back(make_pair(i,x));
	
    }
	
 
	
 
	
    int currentNode=n;
	
 
	
    while(1)
	
    {
	
        //for the current Minimum
	
        int dvect=0;
	
 
	
        int cnt=0;
	
 
	
        while(!q.empty() && cnt<2)
	
        {
	
            vect[++dvect]=make_pair(1,q.front());
	
            q.pop_front();
	
            cnt++;
	
        }
	
 
	
        cnt=0;
	
 
	
 
	
        while(!q2.empty() && cnt<2)
	
        {
	
            vect[++dvect]=make_pair(2,q2.front());
	
            q2.pop_front();
	
            cnt++;
	
        }
	
 
	
        reverse(vect+1,vect+dvect+1);
	
 
	
        for(int i=1;i<=dvect;i++)
	
            if(vect[i].first==1) q.push_front(vect[i].second);
	
            else q2.push_front(vect[i].second);
	
 
	
        reverse(vect+1,vect+dvect+1);
	
 
	
        if(dvect<2)
	
            break;
	
 
	
        //stable_sort(vect.begin(),vect.end(),cmp);
	
 
	
 
	
 
	
        pair<int,pair<int,int> > pr1={0,{0,INT_MAX}};
	
        pair<int,pair<int,int> > pr2={0,{0,INT_MAX}};
	
 
	
        for(int i=1;i<=dvect;i++)
	
            if(vect[i].second.second<pr1.second.second)
	
            {
	
 
	
                pr2=pr1;
	
                pr1=vect[i];
	
            }
	
            else if(vect[i].second.second<pr2.second.second)
	
            {
	
 
	
                pr2=vect[i];
	
            }
	
 
	
        if(pr1.first==1) q.pop_front();
	
        else q2.pop_front();
	
        if(pr2.first==1) q.pop_front();
	
        else q2.pop_front();
	
 
	
        currentNode++;
	
 
	
        g[currentNode-n][0]=pr1.second.first;
	
        g[currentNode-n][1]=pr2.second.first;
	
 
	
        q2.push_back(make_pair(currentNode,pr1.second.second+pr2.second.second));
	
 
	
    }
	
 
	
 
	
    dfs(currentNode,0,0);
	
 
	//edfddfdfsdf
    printf("%lld\n",ans);
	
 
	
 
	
    for(int i=1;i<=n;i++)
	
    {
	
        printf("%d %lld\n",sol[i].first,sol[i].second);
	
    }
	
    return 0;
	
}