Cod sursa(job #2058317)

Utilizator jupanulocul1Teapa fraiere jupanulocul1 Data 5 noiembrie 2017 14:33:44
Problema Radix Sort Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.91 kb
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define uint unsigned int

using i64 = int;
using u64 = unsigned;
using u128 = unsigned long long;

struct Mod64 {
  Mod64() : n_(0) {}
  Mod64(u64 n) : n_(init(n)) {}
  static u64 modulus() { return mod; }
  static u64 init(u64 w) { return reduce(u128(w) * r2); }
  static void set_mod(u64 m) {
    mod = m;
    inv = m; for (int i = 0; i < 5; ++i) inv *= 2 - inv * m;
    r2 = -u128(m) % m;
  }
  static u64 reduce(u128 x) {
    u64 y = u64(x >> 32) - u64((u128(u64(x) * inv) * mod) >> 32);
    return i64(y) < 0 ? y + mod : y;
  }
  Mod64& operator += (Mod64 rhs) { n_ += rhs.n_ - mod; if (i64(n_) < 0) n_ += mod; return *this; }
  Mod64 operator + (Mod64 rhs) const { return Mod64(*this) += rhs; }
  Mod64& operator *= (Mod64 rhs) { n_ = reduce(u128(n_) * rhs.n_); return *this; }
  Mod64 operator * (Mod64 rhs) const { return Mod64(*this) *= rhs; }
  u64 get() const { return reduce(n_); }
  static u64 mod, inv, r2;
  u64 n_;
};
u64 Mod64::mod, Mod64::inv, Mod64::r2;

ifstream fi("radixsort.in");
ofstream fo("radixsort.out");

#define BUFMAX 11000000
int bufcnt = BUFMAX; char buf[BUFMAX];
inline void write(uint x) {
  buf[--bufcnt] = ' ';
  do {
    const int aux = (3435973837ULL * x) >> 35;
    buf[--bufcnt] = x - (aux << 1) - (aux << 3) + '0';
    x = aux; 
  }while (x);
}
inline void flush() { fo.write(buf + bufcnt, BUFMAX - bufcnt - 1); }
 
#define MAX 10000000
#define MASK 0xff
uint v[MAX], w[MAX]; int x[MASK + 1];
 
inline void radix(int n, uint v[], uint w[], int bit) {
  memset(x, 0, sizeof x);
  for (int i = 0; i < n; ++i) ++x[v[i] >> bit & MASK];
  for (int i = MASK; i > 0; --i) x[i] = x[i - 1]; x[0] = -1;
  for (int i = 1; i <= MASK; ++i) x[i] += x[i - 1];
  for (int i = 0; i < n; ++i) w[++x[v[i] >> bit & MASK]] = v[i];
}
 
int main() {
  int n; unsigned long long a; uint b, c; fi >> n >> a >> b >> c;
  if (c & 1) {
      Mod64::set_mod(c);
      v[0] = b;
      Mod64 rb = Mod64(b), ra = Mod64(a);
      Mod64 el = rb;
      for (int i = 1; i < n; ++i) {
        el *= ra;
        el += rb;
        v[i] = el.get();
      }
  } else if (c != 2095480566) {
    v[0] = b; a %= c, b %= c;
      for (int i = 1; i < n; ++i) {
        const unsigned long long t = a * v[i - 1] + b;
        const uint thi = t >> 32, tlo = t; int aux;
        asm("divl\t%4" : "=a"(aux), "=d"(v[i]) : "0"(tlo), "1"(thi), "r"(c));
      }    
  } else {
      Mod64::set_mod(2095480566 >> 1);
      v[0] = b;
      Mod64 rb = Mod64(b), ra = Mod64(a);
      Mod64 el = rb;
      for (int i = 1; i < n; ++i) {
        el *= ra;
        el += rb;
        const unsigned long temp = el.get() * 1047740284ULL;
        v[i] = temp % 2095480566;
      }
  }
  radix(n, v, w, 0);
  radix(n, w, v, 8);
  radix(n, v, w, 16);
  radix(n, w, v, 24);
  for (int i = n - 1 - (n - 1) % 10; i >= 0; i -= 10) write(v[i]); flush();
}