fft
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#define MAXN 1000000
using namespace std;
const double pi = acos ( - 1 ) ;
struct cmplx {
double r, i;
inline cmplx ( ) { r = i = 0 ; }
inline cmplx ( double x, double y) { r = x, i = y; }
inline cmplx operator + ( cmplx & x) { return cmplx ( r + x. r, i + x. i) ; }
inline cmplx operator - ( cmplx & x) { return cmplx ( r - x. r, i - x. i) ; }
inline cmplx operator * ( cmplx & x) { return cmplx ( r * x. r - i * x. i, r * x. i + i * x. r) ; }
inline void operator + = ( cmplx & x) { r + = x. r, i + = x. i; }
inline void operator * = ( cmplx & x) { double t = r; r = r * x. r - i * x. i, i = t * x. i + i * x. r; }
} f[ MAXN] , g[ MAXN] ;
int r[ MAXN] , n, m, lim;
inline int read ( ) {
register int s = 0 , w = 1 ;
register char ch = getchar ( ) ;
while ( ! isdigit ( ch) ) { if ( ch == '-' ) w = - 1 ; ch = getchar ( ) ; }
while ( isdigit ( ch) ) { s = ( s << 3 ) + ( s << 1 ) + ( ch ^ 48 ) ; ch = getchar ( ) ; }
return s * w;
}
inline void FFT ( cmplx * a, int opt) {
for ( register int i = 0 ; i < lim; i++ ) if ( i < r[ i] ) swap ( a[ i] , a[ r[ i] ] ) ;
for ( register int i = 1 ; i < lim; i <<= 1 ) {
cmplx x = cmplx ( cos ( pi / i) , sin ( pi / i) * opt) ;
for ( register int j = 0 ; j < lim; j + = ( i << 1 ) ) {
cmplx y = cmplx ( 1 , 0 ) ;
for ( register int k = 0 ; k < i; k++ , y * = x) {
cmplx p = a[ j + k] , q = a[ i + j + k] * y;
a[ j + k] = p + q, a[ i + j + k] = p - q;
}
}
}
}
int main ( ) {
n = read ( ) , m = read ( ) ; int l = 0 ;
for ( register int i = 0 ; i <= n; i++ ) f[ i] . r = read ( ) ;
for ( register int i = 0 ; i <= m; i++ ) g[ i] . r = read ( ) ;
for ( lim = 1 ; lim <= n + m; lim <<= 1 ) l++ ;
for ( register int i = 0 ; i < lim; i++ ) r[ i] = ( r[ i >> 1 ] >> 1 ) | ( ( i & 1 ) << ( l - 1 ) ) ;
FFT ( f, 1 ) , FFT ( g, 1 ) ;
for ( register int i = 0 ; i <= lim; i++ ) f[ i] * = g[ i] ;
FFT ( f, - 1 ) ;
for ( register int i = 0 ; i <= n + m; i++ ) printf ( "%d " , ( int ) ( 0.5 + f[ i] . r / lim) ) ;
return 0 ;
}
bsgs
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <algorithm>
#define int long long
using namespace std;
int p, a, b, ans;
int pow ( int a, int b, int qy) {
if ( ! b) return 1 ; if ( b == 1 ) return a;
int base = 1 ;
while ( b) {
if ( b & 1 ) base * = a, base % = qy;
a * = a, a % = qy, b >>= 1 ;
}
return base;
}
int BSGS ( int a, int b, int qy) {
map < int , int > hash;
int lim = ceil ( sqrt ( qy) ) , base = b % qy;
for ( register int i = 1 ; i <= lim; i++ ) {
base = base * a % qy; hash[ base] = i;
}
base = pow ( a, lim, qy) ;
int o = 1 ;
for ( register int i = 1 ; i <= lim; i++ ) {
o * = base, o % = qy;
if ( hash[ o] ) return ( ( i * lim - hash[ o] ) % qy + qy) % qy;
}
return - 1 ;
}
signed main ( ) {
scanf ( "%lld%lld%lld" , & p, & a, & b) ;
if ( a % p == 0 ) puts ( "no solution" ) ;
else {
int ans = BSGS ( a, b, p) ;
if ( ans == - 1 ) puts ( "no solution" ) ;
else printf ( "%lld\n" , ans) ;
}
return 0 ;
}
LCT
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 500000
using namespace std;
int father[ MAXN] , val[ MAXN] , son[ MAXN] [ 3 ] , a[ MAXN] , stack[ MAXN] , n, m;
bool rev[ MAXN] ;
inline int read ( ) {
register int s = 0 , w = 1 ;
register char ch = getchar ( ) ;
while ( ! isdigit ( ch) ) { if ( ch == '-' ) w = - 1 ; ch = getchar ( ) ; }
while ( isdigit ( ch) ) { s = ( s << 3 ) + ( s << 1 ) + ( ch ^ 48 ) ; ch = getchar ( ) ; }
return s * w;
}
struct lct {
inline bool isroot ( int x) {
return ! ( son[ father[ x] ] [ 0 ] == x || son[ father[ x] ] [ 1 ] == x) ;
}
inline void maintain ( int x) {
val[ x] = a[ x] ^ val[ son[ x] [ 0 ] ] ^ val[ son[ x] [ 1 ] ] ;
}
inline void pushrev ( int x) {
swap ( son[ x] [ 0 ] , son[ x] [ 1 ] ) , rev[ x] ^ = 1 ;
}
inline void pushdown ( int x) {
if ( rev[ x] ) {
if ( son[ x] [ 0 ] ) pushrev ( son[ x] [ 0 ] ) ;
if ( son[ x] [ 1 ] ) pushrev ( son[ x] [ 1 ] ) ;
rev[ x] ^ = 1 ;
}
}
inline void rotate ( int x) {
int y = father[ x] , z = father[ y] ;
int k = son[ y] [ 1 ] == x, kk = son[ z] [ 1 ] == y;
if ( ! isroot ( y) ) son[ z] [ kk] = x;
father[ x] = z;
son[ y] [ k] = son[ x] [ k ^ 1 ] ;
father[ son[ x] [ k ^ 1 ] ] = y;
son[ x] [ k ^ 1 ] = y;
father[ y] = x;
maintain ( y) , maintain ( x) ;
}
inline void splay ( int x) {
int top = 0 ; stack[ ++ top] = x;
for ( register int i = x; ! isroot ( i) ; i = father[ i] ) stack[ ++ top] = father[ i] ;
for ( register int i = top; i; i-- ) pushdown ( stack[ i] ) ;
while ( ! isroot ( x) ) {
int y = father[ x] , z = father[ y] ;
if ( ! isroot ( y) )
( son[ y] [ 1 ] == x) ^ ( son[ z] [ 1 ] == y)
? rotate ( x) : rotate ( y) ;
rotate ( x) ;
}
maintain ( x) ;
}
inline void access ( int x) { for ( int y= 0 ; x; x= father[ y= x] ) splay ( x) , son[ x] [ 1 ] = y, maintain ( x) ; }
inline void makeroot ( int x) { access ( x) , splay ( x) , pushrev ( x) ; }
inline int findroot ( int x) { access ( x) , splay ( x) ; while ( son[ x] [ 0 ] ) pushdown ( x= son[ x] [ 0 ] ) ; splay ( x) ; return x; }
inline void split ( int x, int y) { makeroot ( x) , access ( y) , splay ( y) ; }
inline void link ( int x, int y) { makeroot ( x) ; if ( findroot ( y) != x) father[ x] = y; }
inline void cut ( int x, int y) { makeroot ( x) ; if ( findroot ( y) == x&& father[ y] == x&& ! son[ y] [ 0 ] ) father[ y] = son[ x] [ 1 ] = 0 , maintain ( x) ; }
inline void query ( int x, int y) { split ( x, y) ; printf ( "%d\n" , val[ y] ) ; }
inline void modify ( int x, int y) { splay ( x) , a[ x] = y; }
} tree;
int main ( ) {
n = read ( ) , m = read ( ) ;
for ( register int i = 1 ; i <= n; i++ ) a[ i] = read ( ) ;
for ( register int i = 1 ; i <= m; i++ ) {
int opt = read ( ) , x = read ( ) , y = read ( ) ;
if ( opt == 0 ) tree. query ( x, y) ;
if ( opt == 1 ) tree. link ( x, y) ;
if ( opt == 2 ) tree. cut ( x, y) ;
if ( opt == 3 ) tree. modify ( x, y) ;
}
return 0 ;
}
树链剖分
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 200010
#define int long long
#define read(a) a = SlowRead <int> ()
#define rep(x,y,z) for (register int x = y; x <= z; x++)
#define cross(x,y) for (register int x = head[now]; x; x = edge[x].next)
using namespace std;
struct fls {
int next, to;
} edge[ MAXN] ;
int n, q, root, qy;
int tree[ MAXN << 2 ] , lazy[ MAXN << 2 ] ;
int id[ MAXN] , rk[ MAXN] , a[ MAXN] , father[ MAXN] , depth[ MAXN] ;
int top[ MAXN] , size[ MAXN] , son[ MAXN] , head[ MAXN << 2 ] , cnt, dfn, res, ans;
template < typename _T> inline _T SlowRead ( ) {
register int s = 0 , w = 1 ;
register char ch = getchar ( ) ;
while ( ! isdigit ( ch) ) { if ( ch == '-' ) w = - 1 ; ch = getchar ( ) ; }
while ( isdigit ( ch) ) { s = ( s << 3 ) + ( s << 1 ) + ch - '0' ; ch = getchar ( ) ; }
return s * w;
}
inline void connect ( int u, int v) {
edge[ ++ cnt] . to = v;
edge[ cnt] . next = head[ u] ;
head[ u] = cnt;
}
namespace segtree {
inline void pushup ( int now) {
tree[ now] = tree[ now << 1 ] + tree[ now << 1 | 1 ] ;
tree[ now] % = qy;
}
inline void pushdown ( int now, int l, int r) {
int mid = ( l+ r) >> 1 ;
lazy[ now << 1 ] + = lazy[ now] ;
lazy[ now << 1 | 1 ] + = lazy[ now] ;
tree[ now << 1 ] + = lazy[ now] * ( mid- l+ 1 ) ;
tree[ now << 1 | 1 ] + = lazy[ now] * ( r- mid) ;
tree[ now << 1 ] % = qy;
tree[ now << 1 | 1 ] % = qy;
lazy[ now] = 0 ;
}
void build ( int now, int l, int r) {
if ( l == r) {
tree[ now] = a[ rk[ l] ] ;
tree[ now] % = qy;
return ;
}
int mid = ( l+ r) >> 1 ;
build ( now << 1 , l, mid) ;
build ( now << 1 | 1 , mid+ 1 , r) ;
pushup ( now) ;
}
void update ( int now, int l, int r, int L, int R, int change) {
if ( R < l || r < L) return ;
if ( L <= l && r <= R) {
tree[ now] + = change * ( r- l+ 1 ) ;
lazy[ now] + = change; return ;
}
if ( lazy[ now] ) pushdown ( now, l, r) ;
int mid = ( l+ r) >> 1 ;
update ( now << 1 , l, mid, L, R, change) ;
update ( now << 1 | 1 , mid+ 1 , r, L, R, change) ;
pushup ( now) ;
}
void query ( int now, int l, int r, int L, int R) {
if ( R < l || r < L) return ;
if ( L <= l && r <= R) {
res + = tree[ now] ;
res % = qy; return ;
}
if ( lazy[ now] ) pushdown ( now, l, r) ;
int mid = ( l+ r) >> 1 ;
query ( now << 1 , l, mid, L, R) ;
query ( now << 1 | 1 , mid+ 1 , r, L, R) ;
}
} using namespace segtree;
namespace tree_split {
inline void MR ( int x, int y, int change) {
change % = qy;
while ( top[ x] != top[ y] ) {
if ( depth[ top[ x] ] < depth[ top[ y] ] ) swap ( x, y) ;
update ( 1 , 1 , n, id[ top[ x] ] , id[ x] , change) ;
x = father[ top[ x] ] ;
}
if ( depth[ x] > depth[ y] ) swap ( x, y) ;
update ( 1 , 1 , n, id[ x] , id[ y] , change) ;
}
inline void QR ( int x, int y) {
while ( top[ x] != top[ y] ) {
if ( depth[ top[ x] ] < depth[ top[ y] ] ) swap ( x, y) ;
res = 0 ;
query ( 1 , 1 , n, id[ top[ x] ] , id[ x] ) ;
ans + = res; ans % = qy;
x = father[ top[ x] ] ;
}
if ( depth[ x] > depth[ y] ) swap ( x, y) ;
res = 0 ;
query ( 1 , 1 , n, id[ x] , id[ y] ) ;
ans + = res; ans % = qy;
}
inline void MT ( int x, int change) {
change % = qy;
update ( 1 , 1 , n, id[ x] , id[ x] + size[ x] - 1 , change) ;
}
inline void QT ( int x) {
res = 0 ;
query ( 1 , 1 , n, id[ x] , id[ x] + size[ x] - 1 ) ;
ans = res;
}
void DFS1 ( int now, int fa, int d) {
father[ now] = fa;
depth[ now] = d;
size[ now] = 1 ;
int maxson = - 1 ;
cross ( i, now) {
int v = edge[ i] . to;
if ( v == fa) continue ;
DFS1 ( v, now, d+ 1 ) ;
size[ now] + = size[ v] ;
if ( size[ v] > maxson) {
maxson = size[ v] ;
son[ now] = v;
}
}
}
void DFS2 ( int now, int top_heavy) {
top[ now] = top_heavy;
id[ now] = ++ dfn;
rk[ dfn] = now;
if ( ! son[ now] ) return ;
DFS2 ( son[ now] , top_heavy) ;
cross ( i, now) {
int v = edge[ i] . to;
if ( v != father[ now] && v != son[ now] ) DFS2 ( v, v) ;
}
}
} using namespace tree_split;
signed main ( ) {
read ( n) , read ( q) , read ( root) , read ( qy) ;
rep ( i, 1 , n) read ( a[ i] ) ;
rep ( i, 1 , n- 1 ) {
int x, y; read ( x) , read ( y) ;
connect ( x, y) , connect ( y, x) ;
}
DFS1 ( root, 0 , 1 ) ; DFS2 ( root, root) ;
build ( 1 , 1 , n) ;
rep ( i, 1 , q) {
int type, l, r, x; read ( type) ;
if ( type == 1 ) {
read ( l) , read ( r) , read ( x) ;
MR ( l, r, x) ;
}
if ( type == 2 ) {
read ( l) , read ( r) ; ans = 0 ;
QR ( l, r) ; printf ( "%lld\n" , ans) ;
}
if ( type == 3 ) {
read ( l) , read ( x) ;
MT ( l, x) ;
}
if ( type == 4 ) {
read ( l) ; ans = 0 ;
QT ( l) ; printf ( "%lld\n" , ans) ;
}
}
return 0 ;
}
splay
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 300000
#define INF 1 << 29
using namespace std;
int n, sz, root;
struct spaly {
int size[ MAXN] , father[ MAXN] , son[ MAXN] [ 3 ] , cnt[ MAXN] , val[ MAXN] ;
inline void maintain ( int x) {
size[ x] = size[ son[ x] [ 0 ] ] + size[ son[ x] [ 1 ] ] + cnt[ x] ;
}
inline void rotate ( int x) {
int y = father[ x] , z = father[ y] ;
int k = son[ y] [ 1 ] == x, kk = son[ z] [ 1 ] == y;
son[ z] [ kk] = x, father[ x] = z,
son[ y] [ k] = son[ x] [ k ^ 1 ] , father[ son[ x] [ k ^ 1 ] ] = y,
son[ x] [ k ^ 1 ] = y, father[ y] = x,
maintain ( y) , maintain ( x) ;
}
inline void splay ( int x, int goal) {
while ( father[ x] != goal) {
int y = father[ x] , z = father[ y] ;
if ( z != goal)
( son[ y] [ 1 ] == x) ^ ( son[ z] [ 1 ] == y)
? rotate ( x) : rotate ( y) ;
rotate ( x) ;
}
if ( ! goal) root = x;
}
inline void find ( int x) {
int now = root;
while ( son[ now] [ x > val[ now] ] && val[ now] != x)
now = son[ now] [ x > val[ now] ] ;
splay ( now, 0 ) ;
}
int Kth ( int x, int rank) {
if ( son[ x] [ 0 ] && rank <= size[ son[ x] [ 0 ] ] ) return Kth ( son[ x] [ 0 ] , rank) ;
return ( rank <= size[ son[ x] [ 0 ] ] + cnt[ x] )
? x : Kth ( son[ x] [ 1 ] , rank - size[ son[ x] [ 0 ] ] - cnt[ x] ) ;
}
inline int prev ( int x) {
int now = root, pre;
while ( now) {
( val[ now] < x)
? pre = now, now = son[ now] [ 1 ]
: now = son[ now] [ 0 ] ;
}
return pre;
}
inline int succ ( int x) {
int now = root, nxt;
while ( now) {
( val[ now] > x)
? nxt = now, now = son[ now] [ 0 ]
: now = son[ now] [ 1 ] ;
}
return nxt;
}
inline void del ( int x) {
int pre = prev ( x) , nxt = succ ( x) ;
splay ( pre, 0 ) , splay ( nxt, pre) ;
int pos = son[ nxt] [ 0 ] ;
if ( cnt[ pos] > 1 ) cnt[ pos] -- , splay ( pos, 0 ) ;
else son[ nxt] [ 0 ] = 0 ;
}
inline void insert ( int x) {
int now = root, fa = 0 ;
while ( now && x != val[ now] ) fa = now, now = son[ now] [ x > val[ now] ] ;
if ( now) cnt[ now] ++ ;
else {
now = ++ sz;
if ( fa) son[ fa] [ x > val[ fa] ] = now;
son[ now] [ 0 ] = son[ now] [ 1 ] = 0 ;
size[ now] = cnt[ now] = 1 ;
val[ now] = x, father[ now] = fa;
}
splay ( now, 0 ) ;
}
} tree;
int main ( ) {
scanf ( "%d" , & n) , tree. insert ( INF) , tree. insert ( - INF) ;
for ( register int i = 1 ; i <= n; i++ ) {
int opt, x; scanf ( "%d%d" , & opt, & x) ;
if ( opt == 1 ) tree. insert ( x) ;
if ( opt == 2 ) tree. del ( x) ;
if ( opt == 3 ) tree. find ( x) , printf ( "%d\n" , tree. size[ tree. son[ root] [ 0 ] ] ) ;
if ( opt == 4 ) printf ( "%d\n" , tree. val[ tree. Kth ( root, x + 1 ) ] ) ;
if ( opt == 5 ) printf ( "%d\n" , tree. val[ tree. prev ( x) ] ) ;
if ( opt == 6 ) printf ( "%d\n" , tree. val[ tree. succ ( x) ] ) ;
}
return 0 ;
}
excrt
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#define int long long
#define MAXN 200000
using namespace std;
int a[ MAXN] , b[ MAXN] , n, x, y;
inline int mul ( int o, int u, int qy) {
int p = 0 ;
while ( u) {
if ( u & 1 ) p = ( p + o) % qy;
o = ( o << 1 ) % qy;
u >>= 1 ;
}
return p;
}
int GCD ( int a, int b) {
if ( ! b) return a;
return GCD ( b, a % b) ;
}
void EXGCD ( int a, int b, int & x, int & y) {
if ( ! b) {
x = 1 ; y = 0 ; return ;
}
EXGCD ( b, a % b, x, y) ;
int tmp = x;
x = y;
y = tmp - a / b * y;
}
void EXCRT ( ) {
int LCM = b[ 1 ] , ans = a[ 1 ] ;
for ( register int i = 2 ; i <= n; i++ , x = 0 , y = 0 ) {
int k = ( ( a[ i] - ans) % b[ i] + b[ i] ) % b[ i] ;
int gcd = GCD ( LCM, b[ i] ) ; if ( k % gcd) return ;
EXGCD ( LCM, b[ i] , x, y) ;
x = mul ( x, k / gcd, b[ i] ) ;
ans + = x * LCM;
LCM * = b[ i] / gcd;
ans = ( ans % LCM + LCM) % LCM;
}
printf ( "%lld\n" , ans) ;
}
signed main ( ) {
scanf ( "%lld" , & n) ;
for ( register int i = 1 ; i <= n; i++ ) scanf ( "%lld%lld" , & b[ i] , & a[ i] ) ;
EXCRT ( ) ;
return 0 ;
}
树状数组套主席
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 100010
using namespace std;
struct ques {
int a, b, c;
} q[ MAXN] ;
int val[ MAXN * 400 ] , L[ MAXN * 400 ] , R[ MAXN * 400 ] , x[ MAXN] , y[ MAXN] ;
int a[ MAXN] , b[ MAXN << 1 ] , root[ MAXN] , n, m, totx, toty, sz, tot;
inline int read ( ) {
register int s = 0 , w = 1 ;
register char ch = getchar ( ) ;
while ( ! isdigit ( ch) ) { if ( ch == '-' ) w = - 1 ; ch = getchar ( ) ; }
while ( isdigit ( ch) ) { s = ( s << 3 ) + ( s << 1 ) + ( ch ^ 48 ) ; ch = getchar ( ) ; }
return s * w;
}
inline int lowbit ( int x) { return x & ( - x) ; }
void insert ( int & o, int l, int r, int from, int x, int v) {
o = ++ sz, val[ o] = val[ from] + v,
L[ o] = L[ from] , R[ o] = R[ from] ;
if ( l == r) return ;
int mid = l + r >> 1 ;
if ( x <= mid) insert ( L[ o] , l, mid, L[ from] , x, v) ;
else insert ( R[ o] , mid + 1 , r, R[ from] , x, v) ;
}
inline void add ( int x, int v) {
int pos = lower_bound ( b + 1 , b + tot + 1 , a[ x] ) - b;
for ( register int i = x; i <= n; i + = lowbit ( i) )
insert ( root[ i] , 1 , tot, root[ i] , pos, v) ;
}
int query ( int o, int l, int r) {
if ( l == r) return r;
int sum = 0 , mid = l + r >> 1 ;
for ( register int i = 1 ; i <= totx; i++ ) sum - = val[ L[ x[ i] ] ] ;
for ( register int i = 1 ; i <= toty; i++ ) sum + = val[ L[ y[ i] ] ] ;
if ( o <= sum) {
for ( register int i = 1 ; i <= totx; i++ ) x[ i] = L[ x[ i] ] ;
for ( register int i = 1 ; i <= toty; i++ ) y[ i] = L[ y[ i] ] ;
return query ( o, l, mid) ;
}
else {
for ( register int i = 1 ; i <= totx; i++ ) x[ i] = R[ x[ i] ] ;
for ( register int i = 1 ; i <= toty; i++ ) y[ i] = R[ y[ i] ] ;
return query ( o - sum, mid + 1 , r) ;
}
}
int main ( ) {
n = read ( ) , m = read ( ) ;
for ( register int i = 1 ; i <= n; i++ ) a[ i] = b[ ++ tot] = read ( ) ;
for ( register int i = 1 ; i <= m; i++ ) {
char opt[ 5 ] ; scanf ( "%s" , opt) ;
if ( opt[ 0 ] == 'Q' ) q[ i] . a = read ( ) , q[ i] . b = read ( ) , q[ i] . c = read ( ) ;
if ( opt[ 0 ] == 'C' ) q[ i] . a = read ( ) , q[ i] . b = b[ ++ tot] = read ( ) ;
}
sort ( b + 1 , b + tot + 1 ) ;
tot = unique ( b + 1 , b + tot + 1 ) - b - 1 ;
for ( register int i = 1 ; i <= n; i++ ) add ( i, 1 ) ;
for ( register int i = 1 ; i <= m; i++ , totx = 0 , toty = 0 )
if ( q[ i] . c) {
for ( register int j = q[ i] . a - 1 ; j; j - = lowbit ( j) ) x[ ++ totx] = root[ j] ;
for ( register int j = q[ i] . b; j; j - = lowbit ( j) ) y[ ++ toty] = root[ j] ;
printf ( "%d\n" , b[ query ( q[ i] . c, 1 , tot) ] ) ;
}
else add ( q[ i] . a, - 1 ) , a[ q[ i] . a] = q[ i] . b, add ( q[ i] . a, 1 ) ;
return 0 ;
}
割点
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 300000
using namespace std;
struct fls {
int to, next;
} edge[ MAXN << 1 ] ;
int head[ MAXN << 1 ] , low[ MAXN] , dfn[ MAXN] , cut[ MAXN] , idx, cnt, ans, n, m;
inline void connect ( int u, int v) {
edge[ ++ cnt] . to = v;
edge[ cnt] . next = head[ u] ;
head[ u] = cnt;
}
void tarjan ( int now, int root) {
dfn[ now] = low[ now] = ++ idx; int sz = 0 ;
for ( register int i = head[ now] ; i; i = edge[ i] . next) {
int v = edge[ i] . to;
if ( ! dfn[ v] ) {
tarjan ( v, root) ;
low[ now] = min ( low[ now] , low[ v] ) ;
if ( low[ v] >= dfn[ now] && now != root) cut[ now] = 1 ;
if ( now == root) sz++ ;
}
low[ now] = min ( low[ now] , dfn[ v] ) ;
}
if ( sz >= 2 && now == root) cut[ now] = 1 ;
}
int main ( ) {
scanf ( "%d%d" , & n, & m) ;
for ( register int i = 1 ; i <= m; i++ ) {
int x, y; scanf ( "%d%d" , & x, & y) ;
connect ( x, y) , connect ( y, x) ;
}
for ( register int i = 1 ; i <= n; i++ )
if ( ! dfn[ i] ) tarjan ( i, i) ;
for ( register int i = 1 ; i <= n; i++ )
if ( cut[ i] ) ans++ ;
printf ( "%d\n" , ans) ;
for ( register int i = 1 ; i <= n; i++ )
if ( cut[ i] ) printf ( "%d " , i) ;
}
缩点
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define MAXN 200000
using namespace std;
struct Front_Link_Star{
int from, to, next;
} edge[ MAXN] , upd_edge[ MAXN] ;
int head[ MAXN] , Stack[ MAXN] , dfn[ MAXN] , low[ MAXN] , top, sd[ MAXN] , n, m, upd_cnt;
int upd_head[ MAXN] , dist[ MAXN] , cnt, tag, indegree[ MAXN] , val[ MAXN] ;
bool vis[ MAXN] ;
inline void Add_Edge ( int u, int v) {
edge[ ++ cnt] . next= head[ u] ;
edge[ cnt] . from= u;
edge[ cnt] . to= v;
head[ u] = cnt;
}
inline int read ( ) {
int s= 0 , w= 1 ;
char ch= getchar ( ) ;
while ( ch< '0' || ch> '9' ) { if ( ch== '-' ) w= - 1 ; ch= getchar ( ) ; }
while ( ch>= '0' && ch<= '9' ) { s= s* 10 + ch- '0' ; ch= getchar ( ) ; }
return s* w;
}
inline void tarjan ( int now) {
dfn[ now] = low[ now] = ++ tag;
vis[ now] = 1 ; Stack[ ++ top] = now;
for ( register int i= head[ now] ; i; i= edge[ i] . next) {
int v= edge[ i] . to;
if ( ! dfn[ v] ) {
tarjan ( v) ;
low[ now] = min ( low[ now] , low[ v] ) ;
} else if ( vis[ v] ) low[ now] = min ( low[ now] , low[ v] ) ;
}
if ( dfn[ now] == low[ now] )
while ( int y= Stack[ top-- ] ) {
sd[ y] = now; vis[ y] = 0 ;
if ( now== y) break ;
val[ now] + = val[ y] ;
}
}
int main ( ) {
n= read ( ) ; m= read ( ) ;
for ( register int i= 1 ; i<= n; i++ )
val[ i] = read ( ) ;
for ( register int i= 1 ; i<= m; i++ ) {
int x= read ( ) , y= read ( ) ;
Add_Edge ( x, y) ;
}
for ( register int i= 1 ; i<= n; i++ )
if ( ! dfn[ i] ) tarjan ( i) ;
return 0 ;
}
kmp
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 1000400
using namespace std;
char a[ MAXN] , b[ MAXN] ;
int fail[ MAXN] , la, lb, n;
int main ( ) {
scanf ( "%s" , a + 1 ) , scanf ( "%s" , b + 1 ) ;
la = strlen ( a + 1 ) , lb = strlen ( b + 1 ) ;
for ( register int i = 2 , j = 0 ; i <= lb; i++ ) {
while ( j && b[ i] != b[ j + 1 ] ) j = fail[ j] ;
if ( b[ i] == b[ j + 1 ] ) j++ ; fail[ i] = j;
}
for ( register int i = 1 , j = 0 ; i <= la; i++ ) {
while ( j && a[ i] != b[ j + 1 ] ) j = fail[ j] ;
if ( a[ i] == b[ j + 1 ] ) j++ ;
if ( j == lb) printf ( "%d\n" , i - lb + 1 ) , j = fail[ j] ;
}
for ( register int i = 1 ; i <= lb; i++ ) printf ( "%d " , fail[ i] ) ;
return 0 ;
}
高斯消元
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#define MAXN 300
using namespace std;
double mat[ MAXN] [ MAXN] , ans[ MAXN] ;
int n;
int main ( ) {
scanf ( "%d" , & n) ;
for ( register int i = 1 ; i <= n; i++ )
for ( register int j = 1 ; j <= n + 1 ; j++ )
scanf ( "%lf" , & mat[ i] [ j] ) ;
for ( register int i = 1 ; i <= n; i++ ) {
int pos = i;
for ( register int j = i + 1 ; j <= n; j++ )
if ( fabs ( mat[ pos] [ i] ) < fabs ( mat[ j] [ i] ) ) pos = j;
if ( fabs ( mat[ pos] [ i] ) < 1e-8 ) {
puts ( "No Solution" ) ;
return 0 ;
}
swap ( mat[ pos] , mat[ i] ) ;
for ( register int j = i + 1 ; j <= n; j++ ) {
double alpha = mat[ i] [ i] / mat[ j] [ i] ;
mat[ j] [ i] = 0 ;
for ( register int k = i + 1 ; k <= n + 1 ; k++ )
mat[ j] [ k] * = alpha, mat[ j] [ k] - = mat[ i] [ k] ;
}
}
for ( register int i = n; i >= 1 ; i-- ) {
ans[ i] = mat[ i] [ n + 1 ] ;
for ( register int j = n; j >= 1 ; j-- )
if ( i != j) ans[ i] - = ans[ j] * mat[ i] [ j] ;
ans[ i] / = mat[ i] [ i] ;
}
for ( register int i = 1 ; i <= n; i++ ) printf ( "%.2lf\n" , ans[ i] ) ;
return 0 ;
}
主席树
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 400000
#define read(a) a = slowread <int> ()
using namespace std;
int root[ MAXN] , a[ MAXN] , b[ MAXN] , n, m, cnt, newsize;
template < typename T> inline T slowread ( ) {
register int s = 0 , w = 1 ;
register char ch = getchar ( ) ;
while ( ! isdigit ( ch) ) { if ( ch == '-' ) w = - 1 ; ch = getchar ( ) ; }
while ( isdigit ( ch) ) { s = ( s << 3 ) + ( s << 1 ) + ( ch ^ 48 ) ; ch = getchar ( ) ; }
return s * w;
}
struct chairtree {
#define mid ((l + r) >> 1)
int L[ MAXN* 40 ] , R[ MAXN* 40 ] , size[ MAXN* 40 ] ;
void build ( int & now, int l, int r) {
now = ++ cnt;
if ( l == r) return ;
build ( L[ now] , l, mid) ;
build ( R[ now] , mid + 1 , r) ;
}
int update ( int from, int l, int r, int change) {
int now = ++ cnt; L[ now] = L[ from] , R[ now] = R[ from] , size[ now] = size[ from] + 1 ;
if ( l == r) return now;
( change <= mid)
? L[ now] = update ( L[ now] , l, mid, change)
: R[ now] = update ( R[ now] , mid + 1 , r, change) ;
return now;
}
int kth ( int tl, int tr, int l, int r, int rank) {
if ( l == r) return l; int delta = size[ L[ tr] ] - size[ L[ tl] ] ;
return ( rank <= delta)
? kth ( L[ tl] , L[ tr] , l, mid, rank)
: kth ( R[ tl] , R[ tr] , mid + 1 , r, rank - delta) ;
}
} tree;
int main ( ) {
read ( n) , read ( m) ;
for ( register int i = 1 ; i <= n; i++ ) read ( a[ i] ) , b[ i] = a[ i] ;
sort ( b + 1 , b + n + 1 ) ; newsize = unique ( b + 1 , b + n + 1 ) - ( b + 1 ) ;
tree. build ( root[ 0 ] , 1 , newsize) ;
for ( register int i = 1 ; i <= n; i++ ) {
int pos = lower_bound ( b + 1 , b + newsize + 1 , a[ i] ) - b;
root[ i] = tree. update ( root[ i - 1 ] , 1 , newsize, pos) ;
}
for ( register int i = 1 ; i <= m; i++ ) {
int l, r, k; read ( l) , read ( r) , read ( k) ;
int pos = tree. kth ( root[ l- 1 ] , root[ r] , 1 , newsize, k) ;
printf ( "%d\n" , b[ pos] ) ;
}
return 0 ;
}