Cod sursa(job #1565822)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 11 ianuarie 2016 14:45:31
Problema Numarare Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.68 kb
#include <cstdio>
#include <cctype>
#include <algorithm>

#define MaxN 100000
#define BUFFSIZE 5500
#define INF 0x3f3f3f3f

using namespace std;

static inline char getChar() {
   static char buff[BUFFSIZE];
   static int pos = BUFFSIZE;

   if (pos == BUFFSIZE) {
      fread(buff, 1, BUFFSIZE, stdin);
      pos = 0;
   }
   return buff[pos++];
}

static inline int readInt() {
   int q = 0;
   char c;
   bool sign = 0;

   do {
      c = getChar();
      sign |= (c == '-');
   } while (!isdigit(c));

   do {
      q = (q << 3) + (q << 1) + (c - '0');
      c = getChar();
   } while (isdigit(c));

   return q ^ ((q ^ -q) & -sign);
}

int v[2 * MaxN + 1]; // pe pozitii impare sirul dat, iar pe cele pare 0
int Z[2 * MaxN + 1]; // manacher

int main() {
   freopen("numarare.in", "r", stdin);
   freopen("numarare.out", "w", stdout);
   int N, l, r;
   int m_search;
   long long rez;

   N = readInt();
   for (int i = 0; i < N; i++) {
      v[2 * i + 1] = readInt();
   }
   fclose(stdin);

   rez = 0LL;
   l = r = 0;
   for (int i = 1; i < N; i++) { // considera 2 * i centru
      if (2 * i <= r) {
         Z[2 * i] = min(Z[2 * (l - i)], r - 2 * i);
      }
      Z[2 * i] += !Z[2 * i];
      m_search = v[2 * i - 1] + v[2 * i + 1];
      while ((2 * (i - 1) >= Z[2 * i])
             && (2 * (i + 1) <= (2 * N) - Z[2 * i])
             && (v[2 * i - Z[2 * i] - 2] + v[2 * i + Z[2 * i] + 2] == m_search)) {
         Z[2 * i] += 2;
      }
      if (2 * i + Z[2 * i] > r) {
         r = 2 * i + Z[2 * i];
         l = 2 * i;
      }
      rez += (Z[2 * i] + 1) / 2LL;
   }

   printf("%lld\n", rez);
   fclose(stdout);
   return 0;
}