Pagini recente » Diferente pentru problema/xcopy intre reviziile 17 si 16 | Cod sursa (job #1850716) | Cod sursa (job #1849724) | Cod sursa (job #2360531) | Cod sursa (job #1180516)
#include <iostream>
#include <fstream>
using namespace std;
template <class T>
class Parser
{
public:
Parser()
{
buffer = new char[BUFFER_SIZE];
position = BUFFER_SIZE;
}
T getNumber( istream &f )
{
return getNr( f );
}
private:
static const int BUFFER_SIZE = ( 1 << 20 );
int position;
char *buffer;
char getChar( istream &f )
{
if ( position == BUFFER_SIZE )
{
f.read( buffer, BUFFER_SIZE );
position = 0;
}
return buffer[ position++ ];
}
T getNr( istream &f )
{
T nr = (T)0;
T sgn = (T)1;
char ch;
do
{
ch = getChar( f );
if ( ch == '-' ) break;
} while ( !isdigit( ch ) );
if ( ch == '-' )
{
sgn = (T)-1;
ch = getChar( f );
}
do
{
nr = nr * (T)10 + ( ch - '0' );
ch = getChar( f );
if ( ch == '.' ) break;
} while ( isdigit( ch ) );
T pw10 = (T)10;
if ( ch == '.' )
{
ch = getChar( f );
do
{
nr = ( nr * pw10 + ( ch - '0' ) ) / pw10;
pw10 *= (T)10;
ch = getChar( f );
} while( isdigit( ch ) );
}
return ( nr * sgn );
}
};
template <class T, T(*F)(T,T)>
class SQRTD
{
const int INF = 1e9;
public:
SQRTD(){ }
SQRTD( const int n, T a[] )
{
alloc_memory( n, a );
}
void alloc_memory( const int n, T a[] )
{
N = n;
v = new T[N + 2];
belong = new int[N + 2];
for ( int i = 1; i <= N; ++i )
{
v[i] = a[i];
belong[i] = 0;
}
SQRT = 1;
while ( SQRT * SQRT < N ) SQRT++;
d = new T[SQRT + 2];
st = new int[SQRT + 2];
dr = new int[SQRT + 2];
for ( int i = 1; i <= SQRT; ++i )
{
d[i] = -INF;
st[i] = INF;
dr[i] = 0;
}
for ( int i = 1, x = 0; i <= N; ++i )
{
if ( i % SQRT == 1 ) x++;
belong[i] = x;
}
for ( int i = 1, x = 0; i <= N; ++i )
{
if ( i % SQRT == 1 ) x++;
st[x] = min( st[x], i );
dr[x] = max( dr[x], min( st[x] + SQRT - 1, N ) );
}
init_decomposition();
}
T combine( T a, T b )
{
if ( a == -INF ) a = b;
else a = F( a, b );
return a;
}
void init_decomposition()
{
for ( int i = 1; i <= N; ++i )
{
d[ belong[i] ] = combine( d[ belong[i] ], v[i] );
}
}
void update( int pos, T new_val )
{
v[pos] = new_val;
int apart = belong[pos];
d[apart] = -INF;
for ( int x = st[apart]; x <= dr[apart]; ++x )
{
d[apart] = combine( d[apart], v[x] );
}
}
T query( int x, int y )
{
int apart_x = belong[x];
int apart_y = belong[y];
T sol = -INF;
for ( int k = max( st[apart_x], x ); k <= min( dr[apart_x], y ); ++k )
{
if ( sol == -INF ) sol = v[k];
else sol = F( sol, v[k] );
}
for ( int k = apart_x + 1; k <= apart_y - 1; ++k )
{
if ( sol == -INF ) sol = d[k];
else sol = F( sol, d[k] );
}
if ( apart_x != apart_y )
{
for ( int k = st[apart_y]; k <= min( dr[apart_y], y ); ++k )
{
if ( sol == -INF ) sol = v[k];
else sol = F( sol, v[k] );
}
}
return sol;
}
private:
T *v, *d;
int *belong, *st, *dr;
int N, SQRT;
};
int maxim( int a, int b )
{
return max( a, b );
}
int a[100000 + 5];
int N, M;
int main()
{
ifstream f("arbint.in");
ofstream g("arbint.out");
Parser <int> P;
N = P.getNumber( f );
M = P.getNumber( f );
for ( int i = 1; i <= N; ++i )
a[i] = P.getNumber( f );
SQRTD <int, maxim> R( N, a );
for ( int i = 1, a, b, c; i <= M; ++i )
{
a = P.getNumber( f );
b = P.getNumber( f );
c = P.getNumber( f );
if ( a == 0 )
{
g << R.query( b, c ) << "\n";
}
else
{
R.update( b, c );
}
}
return 0;
}