User talk:Xreborner

math.cpp


 * 1) include
 * 2) include

using namespace std;

typedef __int64 hugeint;

int gcd(int A, int B) { while (A != 0) {		int C = B % A;		B = A;		A = C;	} return B; }

int gcd(int A, int B, int& S, int& T) { if (A == 0) {		S = 0; T = 1; return B;	} int R = gcd(B % A, A, T, S); S -= B / A * T;	return R; }

hugeint multiply_mod(hugeint A, hugeint B, hugeint C) // return A*B mod C { hugeint R, D;	R = 0; D = A;	while (B > 0) {		if (B % 2 == 1) R = (R + D) % C;		D = (D + D) % C;		B /= 2; }	return R; }

int power_mod(int A, int B, int C) // return A^B mod C { int R = 1, D = A % C;	while (B > 0) {		if (B % 2 == 1) R = hugeint(R) * D % C;		D = hugeint(D) * D % C;		B /= 2; }	return R; }

hugeint power_mod(hugeint A, hugeint B, hugeint C) // return A^B mod C { hugeint R = 1, D = A;	while (B > 0) {		if (B % 2 == 1) R = multiply_mod(R, D, C); D = multiply_mod(D, D, C); B /= 2; }	return R; }

bool quick_check_prime(hugeint Prime, int Times) {	if (Prime < 2) return false; if (Times > Prime - 2) Times = Prime - 2; for (int I = 0; I < Times; I++) if (power_mod(hugeint(I + 2), Prime - 1, Prime) != 1) return false; return true; }

hugeint pollard_rho(hugeint C, hugeint N) // attempt to find a divisor of N, return N if failed {	hugeint I, X, Y, K, D;	I = 1; X = rand % N;	Y = X;	K = 2; do {		I++; D = gcd(N + N + Y - X, N); if (D > 1 && D < N) return D;		if (I == K) Y = X, K *= 2; X = (multiply_mod(X, X, N) + N - C) % N;	} while (Y != X); return N; }

hugeint rho(hugeint N) // return the minimum divisor of N { if (quick_check_prime(N, 50)) return N;	do {		hugeint T = pollard_rho(rand % (N - 1) + 1, N); if (T < N)		{ hugeint A, B;			A = rho(T); B = rho(N / T); return A < B ? A : B;		} }	while (true); }

bool modular_linear_equation(int A, int B, int N, int& M, int Xs[]) // solve a*x mod N = b { int S, T;	int D = gcd(A, N, S, T); if (B % D != 0) return false; int E = B / D * S % N;	M = D;	for (int I = 0; I < D; I++) Xs[I] = E + N / D * I % N;	return true; }

int eular(int N) // return the number of integers coprime with N in 1..N-1 {	if (N == 1) return 0; int M = N;	for (int I = 2; I * I <= N; I++) if (N % I == 0) {			M -= M / I;			N /= I;			while (N % I == 0) N /= I;		} if (N > 1) M -= M / N;	return M; }

int main {	int N, I;	cin >> N;	cout << quick_check_prime(N, 300) << endl; for (I = 2; I * I <= N; I++) if (N % I == 0) break; if (N % I == 0) cout << "0" << endl; else cout << "1" << endl; return 0; } plane.cpp


 * 1) include
 * 2) include
 * 3) include
 * 4) include

using namespace std;

const double Eps = 1e-7;

struct vertex {	double X, Y;	vertex {} vertex(double NewX, double NewY) : X(NewX), Y(NewY) {} double norm const { return X * X + Y * Y; } double abs const { return sqrt(X * X + Y * Y); } vertex rotate const { return vertex(-Y, X); } vertex standard const { double Module = abs; return vertex(X / Module, Y / Module); } };

inline double sqr(double X) { return X * X; }

inline double safe_sqrt(double X) { return X <= 0 ? 0 : sqrt(X); }

inline vertex operator+(vertex A, vertex B) { return vertex(A.X + B.X, A.Y + B.Y); }

inline vertex operator-(vertex A, vertex B) { return vertex(A.X - B.X, A.Y - B.Y); }

inline vertex operator*(vertex A, double K) { return vertex(A.X * K, A.Y * K); }

inline vertex operator/(vertex A, double K) { return vertex(A.X / K, A.Y / K); }

inline double inner_mul(vertex A, vertex B) // return |A| * |B| * cos(AOB) {	return A.X * B.X + A.Y * B.Y; }

inline double inner_mul(vertex A, vertex B, vertex C) { return inner_mul(B - A, C - A); }

inline double cross_mul(vertex A, vertex B) // return |A| * |B| * sin(AOB) {	return A.X * B.Y - A.Y * B.X; }

inline double cross_mul(vertex A, vertex B, vertex C) { return cross_mul(B - A, C - A); }

inline double distance_to(vertex V, vertex A, vertex B) { return cross_mul(V, A, B) / (A - B).abs; }

inline double area_of(double A, double B, double C) { double P = (A + B + C) / 2; return safe_sqrt(P * (P - A) * (P - B) * (P - C)); }

inline vertex intersection_of(vertex A1, vertex A2, vertex B1, vertex B2) {	double S1 = cross_mul(A1, B1, B2), S2 = cross_mul(A2, B2, B1); return (A1 * S2 + A2 * S1) / (S1 + S2); }

inline vertex foot_of(vertex V, vertex A, vertex B) { return intersection_of(V, V + (B - A).rotate, A, B); }

inline pair intersection_of(vertex V, double R, vertex A, vertex B) { vertex Foot = foot_of(V, A, B); vertex Delta = (B - A).standard * safe_sqrt(sqr(R) - sqr(Foot.X - V.X) - sqr(Foot.Y - V.Y)); return make_pair(Foot + Delta, Foot - Delta); }

inline pair intersection_of(vertex V1, double R1, vertex V2, double R2) {	double Dis = (V2 - V1).abs; double H = area_of(Dis, R1, R2) * 2 / Dis; vertex Foot = V1 + (V2 - V1).standard * safe_sqrt(sqr(R1) - sqr(H)); vertex Delta = (V2 - V1).standard.rotate * H;	return make_pair(Foot + Delta, Foot - Delta); }

inline pair tangent_of(vertex V, double R, vertex A) { double Dis = (A - V).abs; double H = R * safe_sqrt(sqr(Dis) - sqr(R)) / Dis; vertex Foot = V + (A - V).standard * safe_sqrt(sqr(R) - sqr(H)); vertex Delta = (A - V).standard * H;	return make_pair(Foot + Delta, Foot - Delta); }

inline vertex outcenter_of(vertex A, vertex B, vertex C) { vertex A1 = (A + B) / 2, B1 = (B + C) / 2; return intersection_of(A1, A1 + (B - A).rotate, B1, B1 + (C - B).rotate); }

inline vertex incenter_of(vertex A, vertex B, vertex C) { double ALen = (B - C).abs, BLen = (A - C).abs, CLen = (B - A).abs; vertex A1 = A + (B - A).standard * (BLen + CLen - ALen) / 2; vertex B1 = B + (C - B).standard * (ALen + CLen - ALen) / 2; return intersection_of(A1, A1 + (B - A).rotate, B1, B1 + (C - B).rotate); }

int main {	return 0; } xnum.cpp


 * 1) include
 * 2) include

using namespace std;


 * 1) define for if (0); else for

typedef __int64 hugeint;

const int Base = 1000000000; const int Capacity = 20;

struct xnum {	int Len; int Data[Capacity]; xnum : Len(0) {} xnum(const xnum& V) : Len(V.Len) { memcpy(Data, V.Data, Len * sizeof *Data); } xnum(int V) : Len(0) { for (V > 0; V /= Base) Data[Len++] = V % Base; } xnum& operator=(const xnum& V) { Len = V.Len; memcpy(Data, V.Data, Len * sizeof *Data); return *this; } int& operator[](int Index) { return Data[Index]; } int operator[](int Index) const { return Data[Index]; } };

int compare(const xnum& A, const xnum& B) { if (A.Len != B.Len) return A.Len > B.Len ? 1 : -1;	int I;	for (I = A.Len - 1; I >= 0 && A[I] == B[I]; I--); if (I < 0) return 0; return A[I] > B[I] ? 1 : -1; }

xnum operator+(const xnum& A, const xnum& B) { xnum R;	int I, Carry = 0; for (I = 0; I < A.Len || I < B.Len || Carry > 0; I++) {		if (I < A.Len) Carry += A[I]; if (I < B.Len) Carry += B[I]; R[I] = Carry % Base; Carry /= Base; }	R.Len = I;	return R; }

xnum operator-(const xnum& A, const xnum& B) { xnum R;	int Carry = 0; R.Len = A.Len; for (int I = 0; I < R.Len; I++) {		R[I] = A[I] - Carry; if (I < B.Len) R[I] -= B[I]; if (R[I] < 0) Carry = 1, R[I] += Base; else Carry = 0; }	while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--; return R; }

xnum operator*(const xnum& A, const int B) { if (B == 0) return 0; xnum R;	hugeint Carry = 0; int I;	for (I = 0; I < A.Len || Carry > 0; I++) {		if (I < A.Len) Carry += hugeint(A[I]) * B;		R[I] = Carry % Base; Carry /= Base; }	R.Len = I;	return R; }

xnum operator*(const xnum& A, const xnum& B) { if (B.Len == 0) return 0; xnum R;	for (int I = 0; I < A.Len; I++) {		hugeint Carry = 0; for (int J = 0; J < B.Len || Carry > 0; J++) {			if (J < B.Len) Carry += hugeint(A[I]) * B[J]; if (I + J < R.Len) Carry += R[I + J]; if (I + J >= R.Len) R[R.Len++] = Carry % Base; else R[I + J] = Carry % Base; Carry /= Base; }		}	return R; }

xnum operator/(const xnum& A, const int B) { xnum R;	hugeint C = 0; for (int I = A.Len - 1; I >= 0; I--) {		C = C * Base + A[I]; R[I] = C / B;		C %= B;	} R.Len = A.Len; while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--; return R; }

xnum operator/(const xnum& A, const xnum& B) { xnum R, Carry = 0; int Left, Right, Mid; for (int I = A.Len - 1; I >= 0; I--) {		Carry = Carry * Base + A[I]; Left = 0; Right = Base - 1; while (Left < Right) {			Mid = (Left + Right + 1) / 2; if (compare(B * Mid, Carry) <= 0) Left = Mid; else Right = Mid - 1; }		R[I] = Left; Carry = Carry - B * Left; }	R.Len = A.Len; while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--; return R; }

istream& operator>>(istream& In, xnum& V) { char Ch; for (V = 0; In >> Ch;) {		V = V * 10 + (Ch - '0'); if (cin.peek <= ' ') break; }	return In; }

ostream& operator<<(ostream& Out, const xnum& V) { Out << (V.Len == 0 ? 0 : V[V.Len - 1]); for (int I = V.Len - 2; I >= 0; I--) for (int J = Base / 10; J > 0; J /= 10) Out << V[I] / J % 10; return Out; }

int main {	return 0; } leftist_tree.cpp


 * 1) include

using namespace std;

typedef int key;

struct leftist_node {	int Weight; key Key; leftist_node *Left, *Right; static leftist_node Nil; };

leftist_node leftist_node::Nil = {0};

void create(leftist_node*& Heap) {	Heap = &leftist_node::Nil; }

void create(leftist_node*& Heap, int Key) {	Heap = new leftist_node; Heap->Weight = leftist_node::Nil.Weight + 1; Heap->Key = Key; Heap->Left = Heap->Right = &leftist_node::Nil; }

void clear(leftist_node* Heap) {	if (Heap != &leftist_node::Nil) {		clear(Heap->Left); clear(Heap->Right); delete Heap; } }

leftist_node* merge(leftist_node* A, leftist_node* B) { if (A == &leftist_node::Nil) return B;	if (B == &leftist_node::Nil) return A;	leftist_node* C;	if (A->Key > B->Key) C = A, A = B, B = C;	A->Right = merge(A->Right, B); if (A->Right->Weight > A->Left->Weight) C = A->Left, A->Left = A->Right, A->Right = C;	A->Weight = A->Right->Weight + 1; return A; }

void insert(leftist_node*& Heap, key Key) {	leftist_node* X;	create(X, Key); Heap = merge(Heap, X); }

key pop(leftist_node*& Heap) {	leftist_node* X = Heap; key Key = X->Key; Heap = merge(X->Left, X->Right); delete X;	return Key; }

int main {	int I;	leftist_node* Heap, *Heap2; create(Heap); for (I = 0; I < 1000000; I++) insert(Heap, rand); create(Heap2); for (I = 0; I < 1000000; I++) insert(Heap2, rand); Heap = merge(Heap, Heap2); for (I = 0; I < 2000000; I++) pop(Heap); clear(Heap); return 0; } rb_tree.cpp


 * 1) include
 * 2) include

using namespace std;

typedef int key;

struct rb_node {	bool Red; key Key; rb_node *Parent, *Child[2]; static rb_node Nil; };

rb_node rb_node::Nil = {false};

void create(rb_node*& Tree) {	Tree = &rb_node::Nil; }

void clear(rb_node* Tree) {	if (Tree != &rb_node::Nil) {		clear(Tree->Child[0]); clear(Tree->Child[1]); delete Tree; } }

rb_node* next(rb_node* X, int Dir = 1) {	if (X->Child[Dir] != &rb_node::Nil) {		X = X->Child[Dir]; while (X->Child[Dir ^ 1] != &rb_node::Nil) X = X->Child[Dir ^ 1]; return X;	} rb_node* Y = X->Parent; while (Y != &rb_node::Nil && X == Y->Child[Dir]) {		X = Y;		Y = Y->Parent; }	return Y; }

rb_node* find(rb_node* X, key Key) {	while (X != &rb_node::Nil && Key != X->Key) X = X->Child[int(Key >= X->Key)]; return X; }

rb_node* lower_bound(rb_node* X, key Key) {	rb_node* Y = &rb_node::Nil; while (X != &rb_node::Nil) if (X->Key < Key) X = X->Child[1]; else {			Y = X;			X = X->Child[0]; }	return Y; }

rb_node* upper_bound(rb_node* X, key Key) {	rb_node* Y = &rb_node::Nil; while (X != &rb_node::Nil) if (X->Key <= Key) X = X->Child[1]; else {			Y = X;			X = X->Child[0]; }	return Y; }

void update(rb_node* X) { }

void update_path(rb_node* X) { while (X != &rb_node::Nil) {		update(X); X = X->Parent; } }

void rotate(rb_node*& Tree, rb_node* X, int Dir) {	rb_node* Y = X->Child[Dir ^ 1]; X->Child[Dir ^ 1] = Y->Child[Dir]; Y->Child[Dir]->Parent = X;	Y->Parent = X->Parent; if (X->Parent == &rb_node::Nil) Tree = Y;	else X->Parent->Child[int(X != X->Parent->Child[0])] = Y;	Y->Child[Dir] = X;	X->Parent = Y;	update(X); update(Y); }

void insert_fixup(rb_node*& Tree, rb_node* X) { while (X->Parent->Red) {		int Dir = int(X->Parent != X->Parent->Parent->Child[0]); rb_node* Y = X->Parent->Parent->Child[Dir ^ 1]; if (Y->Red) {			X->Parent->Red = false; Y->Red = false; X->Parent->Parent->Red = true; X = X->Parent->Parent; }		else {			if (X == X->Parent->Child[Dir ^ 1]) rotate(Tree, X = X->Parent, Dir); X->Parent->Red = false; X->Parent->Parent->Red = true; rotate(Tree, X->Parent->Parent, Dir ^ 1); }	}	Tree->Red = false; }

rb_node* insert(rb_node*& Tree, key Key) {	rb_node* Y = &rb_node::Nil; rb_node* X = Tree; while (X != &rb_node::Nil) {		Y = X;		X = X->Child[int(Key >= X->Key)]; }	X = new rb_node; X->Red = true; X->Key = Key; X->Parent = Y;	X->Child[0] = X->Child[1] = &rb_node::Nil; if (Y == &rb_node::Nil) Tree = X;	else Y->Child[int(Key >= Y->Key)] = X;	update_path(X); insert_fixup(Tree, X); return X; }

void erase_fixup(rb_node*& Tree, rb_node* X) { while (X != Tree && !X->Red) {		rb_node* Z = X->Parent; // X may be nil int Dir = int(X != Z->Child[0]); rb_node* Y = Z->Child[Dir ^ 1]; if (Y->Red) {			Y->Red = false; Z->Red = true; rotate(Tree, Z, Dir); Y = Z->Child[Dir ^ 1]; }		if (!Y->Child[Dir]->Red && !Y->Child[Dir ^ 1]->Red) {			Y->Red = true; X = Z;		} else {			if (!Y->Child[Dir ^ 1]->Red) {				Y->Child[Dir]->Red = false; Y->Red = true; rotate(Tree, Y, Dir ^ 1); Y = Z->Child[Dir ^ 1]; }			Y->Red = Z->Red; Z->Red = false; Y->Child[Dir ^ 1]->Red = false; rotate(Tree, Z, Dir); X = Tree; }	}	X->Red = false; }

void erase(rb_node*& Tree, rb_node* X) { rb_node* Y = X;	rb_node* Z;	if (Y->Child[0] == &rb_node::Nil) Z = Y->Child[1]; else if (Y->Child[1] == &rb_node::Nil) Z = Y->Child[0]; else {		Y = next(X); Z = Y->Child[1]; }	Z->Parent = Y->Parent; if (Y->Parent == &rb_node::Nil) Tree = Z;	else Y->Parent->Child[int(Y != Y->Parent->Child[0])] = Z;	bool Red = Y->Red; if (X != Y)	{ Y->Parent = X->Parent; Y->Child[0] = X->Child[0]; Y->Child[1] = X->Child[1]; Y->Red = X->Red; if (X->Parent == &rb_node::Nil) Tree = Y;		else X->Parent->Child[int(X != X->Parent->Child[0])] = Y;		X->Child[0]->Parent = Y;		X->Child[1]->Parent = Y;	} if (Z == &rb_node::Nil) update_path(Z->Parent); else update_path(Z); if (!Red) erase_fixup(Tree, Z); delete X; }

int main {	int I;	int* P = new int[1000000]; srand(0); for (I = 0; I < 1000000; I++) P[I] = rand % 1000; rb_node* Tree; create(Tree); for (I = 0; I < 1000000; I++) insert(Tree, P[I]); for (I = 0; I < 1000000; I++) erase(Tree, find(Tree, P[I])); clear(Tree); /*multiset Map; for (I = 0; I < 1000000; I++) Map.insert(P[I]); for (I = 0; I < 1000000; I++) Map.erase(Map.find(P[I]));*/ return 0; } relable_to_front.cpp


 * 1) include
 * 2) include
 * 3) include

using namespace std;

typedef int value;

struct max_flow {	static const int max_size = 5000; int N, Sour, Target; value (*Caps)[max_size]; value (*Flows)[max_size]; value Excesses[max_size]; int Heights[max_size]; int Currents[max_size]; };

void create(max_flow& Graph, int N, int Sour, int Target, value Caps[][max_flow::max_size], value Flows[][max_flow::max_size]) {	Graph.N = N;	Graph.Sour = Sour; Graph.Target = Target; Graph.Caps = Caps; Graph.Flows = Flows; }

bool push(max_flow& Graph, int U, int V) { value (*Flows)[max_flow::max_size] = Graph.Flows; value *Excesses = Graph.Excesses; value Delta = Graph.Caps[U][V] - Flows[U][V]; if (Excesses[U] <= Delta) Delta = Excesses[U]; Flows[V][U] = -(Flows[U][V] += Delta); Excesses[U] -= Delta; Excesses[V] += Delta; return Excesses[U] == 0; }

void relable(max_flow& Graph, int U) { /*int H = 0x7fffffff; for (int I = 0; I != Graph.N; I++) if (Graph.Heights[I] < H && Graph.Caps[U][I] > Graph.Flows[U][I]) H = Graph.Heights[I]; Graph.Heights[U] = H + 1;*/ Graph.Heights[U]++; }

bool discharge(max_flow& Graph, int U) { if (Graph.Excesses[U] <= 0) return false; value (*Caps)[max_flow::max_size] = Graph.Caps; value (*Flows)[max_flow::max_size] = Graph.Flows; int *Heights = Graph.Heights; int *Currents = Graph.Currents; bool Relabled = false; for {		int V = Currents[U]; if (V == Graph.N)		{ relable(Graph, U); Relabled = true; Currents[U] = 0; }		else if (Caps[U][V] > Flows[U][V] && Heights[U] == Heights[V] + 1 && push(Graph, U, V)) return Relabled; else Currents[U]++; } }

void perform(max_flow& Graph, int Bound) {	int I, J, U, V;	int N = Graph.N;	int Sour = Graph.Sour; int Target = Graph.Target; value (*Caps)[max_flow::max_size] = Graph.Caps; value (*Flows)[max_flow::max_size] = Graph.Flows; value *Excesses = Graph.Excesses; int *Heights = Graph.Heights; int *Currents = Graph.Currents;

for (I = 0; I != N; I++) Heights[I] = 0; Heights[Sour] = N;	for (I = 0; I != N; I++) Flows[I][Sour] = -(Flows[Sour][I] = Caps[Sour][I]); for (I = 0; I != N; I++) Excesses[I] = 0; for (I = 0; I != N; I++) for (J = 0; J != N; J++) Excesses[I] += Flows[J][I]; for (I = 0; I != Graph.N; I++) Graph.Currents[I] = 0;

int Queue[max_flow::max_size]; int Len = 0; for (I = 0; I != N; I++) if (I != Sour && I != Target) Queue[Len++] = I;	Queue[Len] = Target; for (U = 0; U < Len;) {		I = Queue[U]; if (Excesses[Target] >= Bound) return; if (discharge(Graph, I)) {			V = U;			for (U > 0 && Heights[Queue[U - 1]] < Heights[I]; U--) Queue[U] = Queue[U - 1]; Queue[U++] = I;			if (Heights[Queue[V]] > Heights[Queue[V + 1]] + 1 && Heights[Queue[V]] <= N)			{ while (V >= 0 && Heights[Queue[V]] <= N)				{ Heights[Queue[V]] = N + 1; Currents[Queue[V--]] = 0; }				U = V + 1; }		}		else U++; } }

int N; int Caps[5000][5000]; int Flows[5000][5000]; max_flow Graph;

int main {	int I, J;	N = 5000; cin >> I;	srand(I); for (I = 0; I < N; I++) for (J = 0; J < N; J++) if (I == J) Caps[I][J] = 0; else Caps[I][J] = rand % 2; for (I = 0; I < N; I++) for (J = 0; J < N; J++) Flows[I][J] = 0; create(Graph, N, 0, 1, Caps, Flows); perform(Graph, 0x7fffffff); if (Graph.Excesses[0] != -Graph.Excesses[1]) cout << "!!!" << endl; cout << Graph.Excesses[1] << endl; return 0; } suffix_array.cpp


 * 1) include

using namespace std;

typedef char key;

void sort_suffix(int N, int M, const key Text[], int Orders[], int Ranks[]) {	int I, J, K, L;	int* P1 = new int[max(N, M)]; int* P2 = new int[N];

memset(P1, 0, M * sizeof *P1); for (I = 0; I != N; I++) P1[Text[I]]++; J = P1[0]; P1[0] = 0; for (I = 1; I != M; I++) {		K = P1[I]; P1[I] = J;		J += K;	} for (I = 0; I != N; I++) Ranks[I] = P1[Text[I]]; for (I = 0; I != N; I++) P1[Ranks[I]] = Ranks[I]; for (I = 0; I != N; I++) Orders[P1[Ranks[I]]++] = I;

for (L = 1; L < N; L += L)	{ for (I = 0; I != N; I++) P1[Ranks[I]] = Ranks[I]; for (I = N - L; I != N; I++) P2[P1[Ranks[I]]++] = I;		for (I = 0; I != N; I++) if (Orders[I] >= L)				P2[P1[Ranks[Orders[I] - L]]++] = Orders[I] - L;		memcpy(Orders, P2, N * sizeof *Orders); P1[Orders[0]] = 0; J = 1; for (I = 1; I != N; I++) if (Ranks[Orders[I]] == Ranks[Orders[I - 1]] &&				Orders[I] + L != N && Orders[I - 1] + L != N &&				Ranks[Orders[I] + L] == Ranks[Orders[I - 1] + L]) {				J++; P1[Orders[I]] = P1[Orders[I - 1]]; }			else {				P1[Orders[I]] = P1[Orders[I - 1]] + J;				J = 1; }		memcpy(Ranks, P1, N * sizeof *Ranks); }

delete[] P2; delete[] P1; }

int N; char Text[1000001]; int Orders[1000000]; int Ranks[1000000];

int main {	int I;	/*cin.getline(Text, sizeof Text); N = strlen(Text); sort_suffix(N, 256, Text, Orders, Ranks); for (I = 0; I != N; I++) cout << Text + Orders[I] << endl;*/ N = 1000000; for (I = 0; I != N; I++) Text[I] = rand % 26; sort_suffix(N, 26, Text, Orders, Ranks); return 0; } suffix_tree.cpp


 * 1) include
 * 2) include
 * 3) include

using namespace std;

typedef char value;

struct suffix_node {	value* Start; int Length; suffix_node* Parent; suffix_node* Next; };

struct suffix {	suffix_node* Origin; value* Start; int Length; };

struct suffix_tree {	static const int max_length = 1000001; static const int max_nodes = max_length * 2 + 1; static const int hash_size = max_nodes * 1.1; int Length, NodeCount; suffix Current; value Sequence[max_length]; suffix_node Nodes[max_nodes]; suffix_node* Hash[hash_size]; };

suffix_node* new_node(suffix_tree& Tree, value* Start, int Length, suffix_node* Parent, suffix_node* Next) {	suffix_node* Node = Tree.Nodes + Tree.NodeCount++; Node->Start = Start; Node->Length = Length; Node->Parent = Parent; Node->Next = Next; return Node; }

void create(suffix_tree& Tree) {	Tree.Length = 0; Tree.NodeCount = 0; Tree.Current.Origin = new_node(Tree, 0, 0, 0, 0); Tree.Current.Start = Tree.Sequence; Tree.Length = 0; memset(Tree.Hash, 0, sizeof Tree.Hash); }

suffix_node*& find_child(suffix_tree& Tree, suffix_node* Parent, value Value) {	static const double golden_section = (sqrt(5.0) - 1) / 2; double Temp = ((int&)Parent + Value * 97) * golden_section; int Key = int((Temp - (int)Temp) * suffix_tree::hash_size); suffix_node** Hash = Tree.Hash; while (Hash[Key] != 0 && (Hash[Key]->Parent != Parent || *Hash[Key]->Start != Value)) if (++Key == suffix_tree::hash_size) Key = 0; return Hash[Key]; }

suffix_node* split_edge(suffix_tree& Tree, suffix& Suffix) {	suffix_node* Origin = Suffix.Origin; suffix_node*& EdgeRef = find_child(Tree, Origin, *Suffix.Start); suffix_node* Edge = EdgeRef; EdgeRef = new_node(Tree, Edge->Start, Suffix.Length, Origin, Origin->Next); Edge->Start += Suffix.Length; if (Edge->Length >= 0) Edge->Length -= Suffix.Length; Edge->Parent = EdgeRef; find_child(Tree, EdgeRef, *Edge->Start) = Edge; return EdgeRef; }

suffix_node* canonize(suffix_tree& Tree, suffix& Suffix) {	for {		if (Suffix.Length == 0) return 0; suffix_node* Node = find_child(Tree, Suffix.Origin, *Suffix.Start); if (Node->Length < 0 || Suffix.Length < Node->Length) return Node; Suffix.Origin = Node; Suffix.Start += Node->Length; Suffix.Length -= Node->Length; } }

void append(suffix_tree& Tree, value Value) {	Tree.Sequence[Tree.Length++] = Value; suffix_node* LastParent = 0; suffix& Current = Tree.Current; for {		suffix_node* Parent; suffix_node* Edge = canonize(Tree, Current); if (Edge == 0) {			Parent = Current.Origin; suffix_node*& EdgeRef = find_child(Tree, Parent, Value); if (EdgeRef != 0) break; EdgeRef = new_node(Tree, Tree.Sequence + Tree.Length - 1, -1, Parent, Parent->Next); }		else {			if (Edge->Start[Current.Length] == Value) break; Parent = split_edge(Tree, Current); find_child(Tree, Parent, Value) = new_node(Tree, Tree.Sequence + Tree.Length - 1, -1, Parent, Parent->Next); }		if (LastParent != 0) LastParent->Next = Parent; LastParent = Parent; if (Current.Origin->Parent == 0) {			Current.Start++; Current.Length--; if (Current.Length < 0) break; }		else Current.Origin = Current.Origin->Next; }	if (LastParent != 0) LastParent->Next = Current.Origin; Current.Length++; canonize(Tree, Current); }

void print(suffix_tree& Tree, suffix_node* Node, int Pad) {	int I;	value Value; printf("%*s", Pad, ""); if (Node->Length >= 0) for (I = 0; I < Node->Length; I++) printf("%c", Node->Start[I]); else for (I = int(Node->Start - Tree.Sequence); I < Tree.Length; I++) printf("%c", Tree.Sequence[I]); printf("\n"); for (Value = -128; Value < 127; Value++) {		suffix_node* Edge = find_child(Tree, Node, Value); if (Edge != 0) print(Tree, Edge, Pad + Node->Length); } }

suffix_tree Tree;

int main {	int I;	char S[1001]; create(Tree); /*cin.getline(S, sizeof S); for (I = 0; S[I] != 0; I++) append(Tree, S[I]);*/ for (I = 0; I < 1000000; I++) append(Tree, 'A' + rand % 26); append(Tree, 0); //print(Tree, Tree.Nodes, 0); return 0; } 解模线性方程组： const int MaxN = 100; typedef int Matrix[MaxN][MaxN + 1];

void reduce(int x[], int M, int mod) {	for(int i = 0; i <= M; ++i) x[i] = ((x[i] % mod) + mod) % mod; }

void gauss2(Matrix a, int p[], int N, int M, int mod) {	int i, j, v = 0, x, t;

for(i = 0; i < M; ++i) {		for(j = v; j < N; ++j)if(a[j][i])break;

if(j == N)		{ p[i] = -1; continue; }

p[i] = v;		if(j != v)			for(x = 0; x <= M; ++x) t = a[j][x], a[j][x] = a[v][x], a[v][x] = t;

for(j = v + 1; j < N; ++j) while(a[j][i]) {				if(a[v][i] > a[j][i]) {					for(x = 0; x <= M; ++x)a[v][x] -= a[j][x]; reduce(a[v], M, mod); }				else {					for(x = 0; x <= M; ++x)a[j][x] -= a[v][x]; reduce(a[j], M, mod); }			}		++v; } } 解线性方程组


 * 1) include

const double eps = 1e-8;

/*	a系数矩阵 N行M + 1列 p[i]表示Xi所在的行号 p[i]==-1表示此X无法唯一确定

const int MaxN = 100;

typedef double Matrix[MaxN][MaxN + 1];

void gauss(Matrix a, int p[], int N, int M) { int i, j, v = 0, x;	double t;	for(i = 0; i < M; ++i) {		for(j = v; j < N; ++j)if(fabs(a[j][i]) > eps)break;

if(j == N)		{ p[i] = -1; continue; }

p[i] = v;		if(j != v)			for(x = 0; x <= M; ++x) t = a[j][x], a[j][x] = a[v][x], a[v][x] = t;

for(j = v + 1; j < N; ++j) {			t = -a[j][i] / a[v][i]; for(x = 0; x <= M; ++x)a[j][x] += t * a[v][x]; }		++v; } } 矩阵求逆

dmatrix inverse_of(dmatrix P) { assert(rows(P) == columns(P)); int N = rows(P); dmatrix Q;	assign(Q, N, N, 0); for (int I = 0; I < N; I++) Q[I][I] = 1; array Marks(N, false); array List(N); for (int Turn = 0; Turn < N; Turn++) {		int X, Y;		double MaxVal = -numeric_limits ::max; for (int XX = 0; XX < N; XX++) if (!Marks[XX]) for (int YY = 0; YY < N; YY++) if (!Marks[YY]) if (P[XX][YY] > MaxVal) {					MaxVal = P[XX][YY]; X = XX; Y = YY; }		P[X].swap(P[Y]); Q[X].swap(Q[Y]); Marks[X = Y] = true; List[Turn] = X;		for (int YY = 0; YY < N; YY++) if (!Marks[YY]) P[X][YY] /= P[X][Y]; for (int YY = 0; YY < N; YY++) Q[X][YY] /= P[X][Y]; P[X][X] = 1; for (int XX = 0; XX < N; XX++) if (!Marks[XX]) {			double V = P[XX][X] / P[X][X]; for (int YY = 0; YY < N; YY++) if (!Marks[YY]) P[XX][YY] -= P[X][YY] * V;			for (int YY = 0; YY < N; YY++) Q[XX][YY] -= Q[X][YY] * V;			P[XX][X] = 0; }	}	for (int Turn = N - 2; Turn >= 0; Turn--) {		int X = List[Turn]; for (int I = Turn + 1; I < N; I++) {			int XX = List[I]; double V = P[X][XX] / P[XX][XX]; for (int YY = 0; YY < N; YY++) Q[X][YY] -= Q[XX][YY] * V;			P[X][XX] = 0; }	}	return Q; }