verify/data-structure/LC_predecessor_problem.test.cpp
Depends on
Code
#define PROBLEM "https://judge.yosupo.jp/problem/predecessor_problem"
#include "template/template.hpp"
#include "data-structure/integer-set.hpp"
int main () {
int n , q ;
in ( n , q );
string t ;
in ( t );
IntegerSet set ( t );
while ( q -- ) {
int type , k ;
in ( type , k );
if ( type == 0 )
set . add ( k );
else if ( type == 1 )
set . remove ( k );
else if ( type == 2 )
out ( set . contains ( k ));
else if ( type == 3 )
out ( set . min ( k ));
else if ( type == 4 )
out ( set . max ( k ));
}
}
#line 1 "verify/data-structure/LC_predecessor_problem.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/predecessor_problem"
#line 2 "template/template.hpp"
#include <bits/stdc++.h>
using namespace std ;
#line 2 "template/macro.hpp"
#define rep(i, a, b) for (int i = (a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b) - 1; i >= (a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())
#define YN(b) cout << ((b) ? "YES" : "NO") << "\n";
#define Yn(b) cout << ((b) ? "Yes" : "No") << "\n";
#define yn(b) cout << ((b) ? "yes" : "no") << "\n";
#line 6 "template/template.hpp"
#line 2 "template/util.hpp"
using uint = unsigned int ;
using ll = long long int ;
using ull = unsigned long long ;
using i128 = __int128_t ;
using u128 = __uint128_t ;
template < class T , class S = T >
S SUM ( const vector < T > & a ) {
return accumulate ( ALL ( a ), S ( 0 ));
}
template < class T >
inline bool chmin ( T & a , T b ) {
if ( a > b ) {
a = b ;
return true ;
}
return false ;
}
template < class T >
inline bool chmax ( T & a , T b ) {
if ( a < b ) {
a = b ;
return true ;
}
return false ;
}
template < class T >
int popcnt ( T x ) {
return __builtin_popcountll ( x );
}
template < class T >
int topbit ( T x ) {
return ( x == 0 ? - 1 : 63 - __builtin_clzll ( x ));
}
template < class T >
int lowbit ( T x ) {
return ( x == 0 ? - 1 : __builtin_ctzll ( x ));
}
#line 8 "template/template.hpp"
#line 2 "template/inout.hpp"
struct Fast {
Fast () {
cin . tie ( nullptr );
ios_base :: sync_with_stdio ( false );
cout << fixed << setprecision ( 15 );
}
} fast ;
template < class T1 , class T2 >
istream & operator >> ( istream & is , pair < T1 , T2 > & p ) {
return is >> p . first >> p . second ;
}
template < class T1 , class T2 >
ostream & operator << ( ostream & os , const pair < T1 , T2 > & p ) {
return os << p . first << " " << p . second ;
}
template < class T >
istream & operator >> ( istream & is , vector < T > & a ) {
for ( auto & v : a ) is >> v ;
return is ;
}
template < class T >
ostream & operator << ( ostream & os , const vector < T > & a ) {
for ( auto it = a . begin (); it != a . end ();) {
os << * it ;
if ( ++ it != a . end ()) os << " " ;
}
return os ;
}
template < class T >
ostream & operator << ( ostream & os , const set < T > & st ) {
os << "{" ;
for ( auto it = st . begin (); it != st . end ();) {
os << * it ;
if ( ++ it != st . end ()) os << "," ;
}
os << "}" ;
return os ;
}
template < class T1 , class T2 >
ostream & operator << ( ostream & os , const map < T1 , T2 > & mp ) {
os << "{" ;
for ( auto it = mp . begin (); it != mp . end ();) {
os << it -> first << ":" << it -> second ;
if ( ++ it != mp . end ()) os << "," ;
}
os << "}" ;
return os ;
}
void in () {}
template < typename T , class ... U >
void in ( T & t , U & ... u ) {
cin >> t ;
in ( u ...);
}
void out () { cout << " \n " ; }
template < typename T , class ... U , char sep = ' ' >
void out ( const T & t , const U & ... u ) {
cout << t ;
if ( sizeof ...( u )) cout << sep ;
out ( u ...);
}
#line 10 "template/template.hpp"
#line 2 "template/debug.hpp"
#ifdef LOCAL
#define debug 1
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define debug 0
#define show(...) true
#endif
template < class T >
void _show ( int i , T name ) {
cerr << '\n' ;
}
template < class T1 , class T2 , class ... T3 >
void _show ( int i , const T1 & a , const T2 & b , const T3 & ... c ) {
for (; a [ i ] != ',' && a [ i ] != '\0' ; i ++ ) cerr << a [ i ];
cerr << ":" << b << " " ;
_show ( i + 1 , a , c ...);
}
#line 2 "data-structure/integer-set.hpp"
template < class T = int , class U = unsigned long long >
class IntegerSet {
private:
const static T B = 6 , W = 64 , MASK = W - 1 ;
T size ;
vector < T > start ;
vector < U > data ;
static T high_bit ( U x ) {
if ( x == 0 ) return 0 ;
return W - 1 - countl_zero ( x );
}
static T low_bit ( U x ) {
if ( x == 0 ) return W ;
return countr_zero ( x );
}
public:
IntegerSet ( T n ) {
size = n ;
vector < T > len ;
do len . push_back (( n >>= B ) + 1 );
while ( n > 0 );
start = vector < T > ( 1 , 0 );
start . reserve ( len . size () + 1 );
for ( auto v : len ) start . push_back ( start . back () + v );
data = vector < U > ( start . back ());
}
IntegerSet ( string s = "" ) {
size = s . size ();
T n = size ;
vector < T > len ;
do len . push_back (( n >>= B ) + 1 );
while ( n > 0 );
start = vector < T > ( 1 , 0 );
start . reserve ( len . size () + 1 );
for ( const auto v : len ) start . push_back ( start . back () + v );
data = vector < U > ( start . back ());
for ( T i = 0 ; i < s . size (); i ++ )
if ( s [ i ] == '1' ) data [ i >> B ] |= U ( 1 ) << ( i & MASK );
for ( T i = 0 ; i + 1 < len . size (); i ++ )
for ( T j = 0 ; j < len [ i ]; j ++ )
if ( data [ start [ i ] + j ])
data [ start [ i + 1 ] + ( j >> B )] |= U ( 1 ) << ( j & MASK );
}
void add ( T x ) {
for ( T i = 0 ; i + 1 < start . size (); i ++ ) {
data [ start [ i ] + ( x >> B )] |= U ( 1 ) << ( x & MASK );
x >>= B ;
}
}
void remove ( T x ) {
for ( T i = 0 ; i + 1 < start . size (); i ++ ) {
data [ start [ i ] + ( x >> B )] &= ~ ( U ( 1 ) << ( x & MASK ));
if ( data [ start [ i ] + ( x >> B )] != 0 ) return ;
x >>= B ;
}
}
bool contains ( T x ) const { return ( data [ x >> B ] >> ( x & MASK )) & 1 ; }
T min ( T x ) const {
T d = 0 , i = x ;
while ( true ) {
if ( d + 1 >= start . size ()) return - 1 ;
if (( i >> B ) >= start [ d + 1 ] - start [ d ]) return - 1 ;
U m = data [ start [ d ] + ( i >> B )] & (( ~ U ( 0 )) << ( i & MASK ));
if ( m == 0 ) {
d ++ ;
i >>= B ;
i ++ ;
} else {
i = ( i & ~ MASK ) + low_bit ( m );
if ( d == 0 ) break ;
i <<= B ;
d -- ;
}
}
return i ;
}
T max ( T x ) const {
T d = 0 , i = x ;
while ( true ) {
if ( i < 0 ) return - 1 ;
if ( d >= data . size ()) return - 1 ;
U m = data [ start [ d ] + ( i >> B )] & ~ (( ~ U ( 1 )) << ( i & MASK ));
if ( m == 0 ) {
d ++ ;
i >>= B ;
i -- ;
} else {
i = ( i & ~ MASK ) + high_bit ( m );
if ( d == 0 ) break ;
i <<= B ;
i |= MASK ;
d -- ;
}
}
return i ;
}
};
/**
* @brief 整数の集合(64分木)
*/
#line 5 "verify/data-structure/LC_predecessor_problem.test.cpp"
int main () {
int n , q ;
in ( n , q );
string t ;
in ( t );
IntegerSet set ( t );
while ( q -- ) {
int type , k ;
in ( type , k );
if ( type == 0 )
set . add ( k );
else if ( type == 1 )
set . remove ( k );
else if ( type == 2 )
out ( set . contains ( k ));
else if ( type == 3 )
out ( set . min ( k ));
else if ( type == 4 )
out ( set . max ( k ));
}
}
Back to top page