Submission #521813

#TimeUsernameProblemLanguageResultExecution timeMemory
521813Leo121Horses (IOI15_horses)C++14
37 / 100
115 ms27688 KiB
#include "horses.h" #include <bits/stdc++.h> #define forn(i, a, b) for(int i = int(a); i <= int(b); ++ i) #define fora(i, a, b) for(int i = int(a); i >= int(b); -- i) using namespace std; typedef long long ll; const ll mod = 1e9 + 7; const int lim = 5e5; bool stbool[4 * lim + 2]; int stmax[4 * lim + 2]; ll bit[lim + 2]; int n; ll x[lim + 2]; int y[lim + 2]; int posicion[33]; ll valor[33]; int mayor[33]; int dif1 = 0; ll expb(ll numero){ ll res = 1LL; int aux = 1e9 + 5; forn(i, 0, 29){ if(((1 << i) & aux)){ res *= numero; res %= mod; } numero *= numero; numero %= mod; } return res; } void initbool(int nodo, int l, int r){ if(l == r){ stbool[nodo] = (x[l] != 1); return; } int mitad = (l + r) / 2; initbool(nodo * 2, l, mitad); initbool(nodo * 2 + 1, mitad + 1, r); stbool[nodo] = stbool[nodo * 2] | stbool[nodo * 2 + 1]; } int querybool(int nodo, int l, int r, int rango){ if(l > rango){ return 0; } if(!stbool[nodo]){ return 0; } if(l == r){ return l; } int mitad = (l + r) / 2, value; value = querybool(nodo * 2 + 1, mitad + 1, r, rango); if(!value){ value = querybool(nodo * 2, l, mitad, rango); } return value; } void updatebool(int nodo, int l, int r, int pos){ if(pos < l || pos > r){ return; } if(pos == l && pos == r){ stbool[nodo] ^= 1; return; } int mitad = (l + r) / 2; updatebool(nodo * 2, l, mitad, pos); updatebool(nodo * 2, mitad + 1, r, pos); stbool[nodo] = stbool[nodo * 2] | stbool[nodo * 2 + 1]; } void initmax(int nodo, int l, int r){ if(l == r){ stmax[nodo] = y[l]; return; } int mitad = (l + r) / 2; initmax(nodo * 2, l, mitad); initmax(nodo * 2 + 1, mitad + 1, r); stmax[nodo] = max(stmax[nodo * 2], stmax[nodo * 2 + 1]); } int querymax(int nodo, int l, int r, int li, int ls){ if(li > r || ls < l){ return 0; } if(li <= l && ls >= r){ return stmax[nodo]; } int mitad = (l + r) / 2; return max(querymax(nodo * 2, l, mitad, li, ls), querymax(nodo * 2 + 1, mitad + 1, r, li, ls)); } void updatemax(int nodo, int l, int r, int pos, int val){ if(pos < l || pos > r){ return; } if(pos == l && pos == r){ stmax[nodo] = val; return; } int mitad = (l + r) / 2; updatemax(nodo * 2, l, mitad, pos, val); updatemax(nodo * 2 + 1, mitad + 1, r, pos, val); stmax[nodo] = max(stmax[nodo * 2], stmax[nodo * 2 + 1]); } void updatebit(int pos, ll valor){ for(int i = pos; i <= n; i += i & -i){ bit[i] *= valor; bit[i] %= mod; } } ll querybit(int pos){ ll res = 1LL; for(int i = pos; i >= 1; i -= i & -i){ res *= bit[i]; res %= mod; } return res; } ll respuesta(){ int indice = 1; ll auxiliar = 1LL, res; if(n < 30){ forn(i, 2, n){ auxiliar *= x[i]; if(auxiliar < (ll) y[indice]){ auxiliar *= (ll) y[i]; } if(auxiliar >= (ll) y[indice]){ indice = i; auxiliar = 1LL; } else{ auxiliar /= (ll) y[i]; } } res = querybit(indice); res *= (ll) y[indice]; res %= mod; } else{ forn(i, 2, 30){ auxiliar *= valor[i]; if(auxiliar < (ll) mayor[indice] && mayor[i]){ auxiliar *= (ll) mayor[i]; } if(auxiliar >= (ll) mayor[indice]){ auxiliar = 1LL; indice = i; } else if(mayor[i]){ auxiliar /= (ll) mayor[i]; } } res = (valor[indice] == 1LL) ? 1LL : querybit(posicion[indice]); res *= (ll) mayor[indice]; res %= mod; } return res; } int init(int N, int X[], int Y[]) { n = N; forn(i, 0, n - 1){ x[i + 1] = (ll) X[i]; y[i + 1] = Y[i]; bit[i + 1] = 1; } initbool(1, 1, n); initmax(1, 1, n); forn(i, 1, n){ if(x[i] != 1){ updatebit(i, x[i]); dif1 ++; } } posicion[31] = n + 1; ll res; if(n >= 30){ fora(i, 30, max(1, 31 - dif1)){ posicion[i] = querybool(1, 1, n, posicion[i + 1] - 1); valor[i] = x[posicion[i]]; mayor[i] = querymax(1, 1, n, posicion[i], posicion[i + 1] - 1); } fora(i, max(1, 31 - dif1) - 1, 1){ posicion[i] = 0; valor[i] = 1LL; if(posicion[i + 1]){ mayor[i] = querymax(1, 1, n, 1, posicion[i + 1] - 1); } else{ mayor[i] = mayor[i + 1]; } } } /**forn(i, 1, 30){ cout << posicion[i] << " " << mayor[i] << " " << valor[i] << "\n"; }*/ res = respuesta(); return (int) res; } int updateX(int pos, int val) { ll actualiza = x[pos + 1]; if(val != (ll) actualiza){ actualiza = expb(actualiza); actualiza *= (ll) val; actualiza %= mod; updatebit(pos + 1, actualiza); if(val == 1){ updatebool(1, 1, n, pos + 1); dif1 --; } if(val > 1 && x[pos + 1] == 1){ updatebool(1, 1, n, pos + 1); dif1 ++; } if(n >= 30){ if(val == 1){ if(pos + 1 > posicion[1]){ forn(i, 2, 30){ if(posicion[i] == pos + 1){ posicion[i] = posicion[i - 1]; mayor[i] = max(mayor[i], mayor[i - 1]); valor[i] = valor[i - 1]; fora(j, i - 1, 2){ posicion[i] = posicion[i - 1]; mayor[i] = mayor[i - 1]; valor[i] = valor[i - 1]; } break; } } } if(pos + 1 >= posicion[1]){ if(dif1 >= 30){ posicion[1] = querybool(1, 1, n, posicion[2] - 1); mayor[1] = querymax(1, 1, n, posicion[1], posicion[2] - 1); valor[1] = x[posicion[1]]; } else{ posicion[1] = 0; mayor[1] = querymax(1, 1, n, 1, posicion[31 - dif1] - 1); valor[1] = 1LL; } } } else if(x[pos + 1] > 1 && posicion[1] <= pos + 1){ forn(i, 1, 30){ if(posicion[i] == pos + 1){ valor[i] = (ll) val; break; } } } else if(x[pos + 1] == 1 && posicion[1] < pos + 1){ forn(i, 1, 30){ if(posicion[i + 1] > pos + 1){ posicion[i] = pos + 1; valor[i] = (ll) val; mayor[i] = querymax(1, 1, n, pos + 1, posicion[i + 1] - 1); if(i != 1){ if(posicion[i - 1] == 0){ mayor[i - 1] = querymax(1, 1, n, 1, pos); fora(j, i - 2, 1){ mayor[j] = mayor[j + 1]; } } else{ mayor[i - 1] = querymax(1, 1, n, posicion[i - 1], pos); } } break; } else{ posicion[i] = posicion[i + 1]; mayor[i] = mayor[i + 1]; valor[i] = valor[i + 1]; } } } } x[pos + 1] = val; /**forn(i, 1, 30){ cout << posicion[i] << " " << mayor[i] << " " << valor[i] << "\n"; }*/ } ll res = respuesta(); return (int) res; } int updateY(int pos, int val) { updatemax(1, 1, n, pos + 1, val); y[pos + 1] = val; if(n >= 30){ fora(i, 30, 1){ if(pos + 1 >= posicion[i]){ mayor[i] = querymax(1, 1, n, (posicion[i] == 0) ? 1 : posicion[i], posicion[i + 1] - 1); break; } } /**forn(i, 1, 30){ cout << posicion[i] << " " << mayor[i] << " " << valor[i] << "\n"; }*/ } ll res = respuesta(); return (int) res; }

Compilation message (stderr)

horses.cpp: In function 'void updatebit(int, ll)':
horses.cpp:106:28: warning: declaration of 'valor' shadows a global declaration [-Wshadow]
  106 | void updatebit(int pos, ll valor){
      |                         ~~~^~~~~
horses.cpp:17:4: note: shadowed declaration is here
   17 | ll valor[33];
      |    ^~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...