Cod sursa(job #2380597)

Utilizator alexge50alexX AleX alexge50 Data 15 martie 2019 11:04:46
Problema Arbori de intervale Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.69 kb
#include <fstream>
#include <array>
#include <stdint.h>

#pragma GCC optimize ("-O3,-ffast-math")
#pragma GCC target("sse3")

#define o3 __attribute__((optimize("-O3")))
#define always_inline __inline__ __attribute__((always_inline))

#define fast_shit o3 always_inline

const int DIGIT_COUNT = 2313;

uint16_t toRaw(const char *p)
{
    return *reinterpret_cast<const uint16_t*>(p);
}

const int offset = toRaw("00");

fast_shit static bool is2Digits(const char *p)
{
    return ((toRaw(p) - offset) & static_cast<uint16_t>(0b1111000011110000)) == 0;
}

static std::array<char, DIGIT_COUNT> genTable();

class IntParser
{
public:
    IntParser() = delete;
    IntParser(const char *pbegin, const char *pend): m_pbegin(pbegin), m_current(pbegin), m_pend(pend) {}

    fast_shit int parse()
    {
        if(m_current == m_pend) return 0;
        static auto table = genTable();

        int i = 0;

        while(!std::isdigit(*m_current)) m_current++;

        while(is2Digits(m_current))
            i = i * 100 + table[toRaw(m_current) - offset], m_current += 2;

        if(std::isdigit(*m_current))
            i = i * 10 + *m_current - '0', m_current++;

        return i;
    }

private:
    const char * const m_pbegin, * const m_pend;
    const char * m_current;
};

class IntPrinter
{
public:
    void alloc(size_t n) { buffer.reserve(n); }
    const std::string& str() {return buffer; }

    fast_shit void print(long long x)
    {
        int start = static_cast<int>(buffer.size());

        do
        {
            buffer.push_back(static_cast<char>(x % 10 + '0'));
            x /= 10;
        }
        while(x);

        int end = static_cast<int>(buffer.size() - 1);
        while(end > start)
            std::swap(buffer[start++], buffer[end--]);

        buffer.push_back('\n');
    }

private:
    std::string buffer;

};

const int HEURISTIC_ALLOC = 20000;

const int N = 100000 + 1;
int aint[2 * N];

fast_shit void build(int n)
{
  for(int i = n - 1; i > 0; i--)
    aint[i] = std::max(aint[i << 1], aint[i << 1 | 1]);
}

fast_shit void set(int p, int v, int n)
{
  aint[p + n] = v;
  p += n;

  for(int i = p; i > 1; i >>= 1)
    aint[i>>1] = std::max(aint[i], aint[i ^ 1]);
}

fast_shit int query(int l, int r, int n)
{
  int a = 0;

  for(l += n, r+= n; l < r; l >>= 1, r >>= 1)
  {
    if(l & 1)
      a = std::max(a, aint[l++]);

    if(r & 1)
      a = std::max(a, aint[r--]);
  }

  return a;
}

int main()
{

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

  std::string buffer(
            (std::istreambuf_iterator<char>(fin)),
            std::istreambuf_iterator<char>()
  );

  IntParser parser(&(*buffer.begin()), &(*buffer.end()));
  IntPrinter printer;

  printer.alloc(HEURISTIC_ALLOC);

  int n, m;

  n = parser.parse();
  m = parser.parse();

    for(int i = 0; i < n; i++)
    {
        int x;
        x = parser.parse();

        aint[i + n] = x;
    }

    build(n);

    for(int i = 0; i < m; i++)
    {
        int c = parser.parse(), a = parser.parse(), b = parser.parse();

        if(c == 0)
            printer.print(query(a - 1, b, n));
        else set(a - 1, b - 1, n);
    }

  fout.write(printer.str().c_str(), printer.str().size());
}

static std::array<char, DIGIT_COUNT> genTable()
{
    std::array<char, DIGIT_COUNT> table{};

    char c[2];

    for(char i = '0'; i <= '9'; i++)
    {
        for(char j = '0'; j <= '9'; j++)
        {
            c[0] = i;
            c[1] = j;

            table[toRaw(c) - offset] = static_cast<char>((i - '0') * 10 + j - '0');
        }
    }

    return table;
}