Cod sursa(job #1483777)

Utilizator hrazvanHarsan Razvan hrazvan Data 9 septembrie 2015 21:55:55
Problema Heavy Path Decomposition Scor 0
Compilator c Status done
Runda Arhiva educationala Marime 2.17 kb
#include <stdio.h>
#define MAXN 1000000
#define BUFF (1 << 20)
FILE *in, *out;
int nv[MAXN], nq[MAXN], sv, sq, dq, t[2 * MAXN], ad[2 * MAXN];
int n;
long long v[MAXN], q[MAXN];
char ssin[BUFF], ssout[BUFF + 1];
int pin = BUFF, pout = 0;

inline char cif(char ch){
  if(ch >= '0' && ch <= '9')
    return 1;
  return 0;
}

inline char getcharr(){
  if(pin == BUFF){
    fread(ssin, 1, BUFF, in);
    pin = 0;
  }
  pin++;
  return ssin[pin - 1];
}

inline long long getnumm(){
  char ch = getcharr();
  long long rez = 0;
  while(!cif(ch))
    ch = getcharr();
  while(cif(ch)){
    rez *= 10;
    rez += ch - '0';
    ch = getcharr();
  }
  return rez;
}

inline void flush(){
  ssout[pout] = 0;
  fputs(ssout, out);
  pout = 0;
}

inline void punch(char ch){
  ssout[pout] = ch;
  pout++;
  if(pout == BUFF)
    flush();
}

inline void punnr(long long nr){
  long long p10 = 1;
  while(nr / 10 >= p10)
    p10 *= 10;
  while(p10 > 0){
    punch(nr / p10 % 10 + '0');
    p10 /= 10;
  }
}

inline void take(long long *x, int *p){
  if(sv == n){
    *x = q[sq];
    *p = nq[sq];
    sq++;
  }
  else  if(sq == dq){
    *x = v[sv];
    *p = nv[sv];
    sv++;
  }
  else{
    if(v[sv] > q[sq]){
      *x = q[sq];
      *p = nq[sq];
      sq++;
    }
    else{
      *x = v[sv];
      *p = nv[sv];
      sv++;
    }
  }
}

int main(){
  in = fopen("huffman.in", "r");
  int i;
  n = (int)getnumm();
  for(i = 0; i < n; i++){
    v[i] = getnumm();
    nv[i] = i;
  }
  fclose(in);
  long long sum = 0, x1, x2;
  int p1, p2;
  for(i = 0; i < n - 1; i++){
    take(&x1, &p1);
    take(&x2, &p2);
    q[dq] = x1 + x2;
    sum += q[dq];
    nq[dq] = n + i;
    t[p1] = t[p2] = nq[dq];
    ad[p1] = 0;
    ad[p2] = 1;
    dq++;
  }
  out = fopen("huffman.out", "w");
  punnr(sum);
  punch('\n');
  int poz;
  long long et, nr;
  for(i = 0; i < n; i++){
    poz = i;
    et = 0;
    nr = 0;
    while(poz != 2 * n - 2){
      et += ad[poz] * (1LL << nr);
      poz = t[poz];
      nr++;
    }
    punnr(nr);
    punch(' ');
    punnr(et);
    punch('\n');
  }
  flush();
  fclose(out);
  return 0;
}