1. 程式人生 > 遊戲 >《生化危機》官方釋出“保護傘”公司主題腕錶

《生化危機》官方釋出“保護傘”公司主題腕錶

整理一下常用的板子

整理一下常用的板子qwq

線性篩素數

這個其實只是篩素數的話是挺簡單的,但是我決定連\(\phi\)一起篩出來(如果用不到的話就把\(phi\)陣列自動忽略掉就好了)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

const int N = 5e5 + 10;

int n , cnt;
int prime[N] , phi[N];
bool flag[N];

int main ( void ) {
	flag[1] = 1;
	phi[1] = 1;
	scanf ( "%d" , &n );
	for ( int i = 2 ; i <= n ; i++ ) {
		if ( !flag[i] ) {
			flag[i] = 1;
			prime[++cnt] = i;
			phi[i] = i - 1;
		}
		for ( int j = 1 ; j <= cnt && i * prime[j] <= n ; j++ ) {
			flag[i * prime[j]] = 1;
			if ( i % prime[j] == 0 ) {
				phi[i * prime[j]] = phi[i] * prime[j];
				break;
			}
			phi[i * prime[j]] = phi[i] * phi[prime[j]];
		}
	}
	for ( int i = 1 ; i <= cnt ; i++ )
		printf ( "%d " , prime[i] );
	puts ( "" );
	for ( int i = 1 ; i <= n ; i++ ) 
		printf ( "%d " , phi[i] );
	return 0;
}

字串蛤希

其實我個人比較傾向於寫自然溢位或者直接隨機一個質數\(qwq\)

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>

typedef unsigned long long ull;
const ull base = 233;
const int N = 1e4;
const int M = 1e3;

int n;
char s[N][M];
ull has[N];

int main ( void ) {
	scanf ( "%d" , &n );
	for ( int i = 1 ; i <= n ; i++ ) 
		scanf ( "%s" , s[i] + 1 );
	for ( int i = 1 ; i <= n ; i++ ) {
		int len = strlen ( s[i] + 1 );
		for ( int j = 1 ; j <= len ; j++ )
			has[i] = has[i] * base + s[i][j];
	}
	std :: sort ( has + 1 , has + 1 + n );
	int ans = 0;
	for ( int i = 1 ; i <= n ; i++ ) 
		if ( has[i] != has[i + 1] )
			ans++;
	printf ( "%d\n" , ans );
	return 0;
}

那麼如何求去掉一位的雜湊值呢?

設去掉第k位,長度為l

\(HS=hs[i-1]*base^{l-i}+hs[l]-hs[i]*base^{l-i};\)

查詢子串hash值

typedef unsigned long long ull;
ull get_hash(int l, int r) {
    return h[r] - h[l - 1] * p[r - l + 1];
}

單源最短路 (有負權邊)

這張圖有負權邊,所以只能寫某已經死掉的\(SPFA\)

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

const int N = 1e4 + 10;
const int M = 1e5 + 10;
using std :: queue;

int n , m , t;
struct Edge {
	int to;
	int data;
	int next;
}e[M];
int head[N] , dis[N];
bool inque[N];

inline int read () {
	int s = 0;
	bool flag = 0;
	char ch = getchar ();
	while ( ch > '9' || ch < '0' ) { if ( ch == '0' ) flag = 1; ch = getchar ();}
	while ( ch >= '0' && ch <= '9' ) { s = s * 10 + ch - '0'; ch = getchar ();}
	return ( flag ) ? -s : s;
}
void Spfa ( int x ) {
	memset ( dis , 0x3f3f3f3f , sizeof ( dis ) );
	inque[x] = 1;dis[x] = 0;
	qu.push ( x );
	while ( !qu.empty () ) {
		int j = qu.front ();
		qu.pop ();
		inque[j] = 0;
		for ( int i = head[j] ; i ; i = e[i].next ) {
			int k = e[i].to;
			if ( dis[k] > dis[j] + e[i].data ) {
				dis[k] = dis[j] + e[i].data;
				if ( !inque[k] ) {
					inque[k] = 1;
					qu.push ( k );
				}
			}
		}
	}
	return;
}

int main ( void ) {
	n = read () , m = read ();
	for ( int i = 1 ; i <= m ; i++ ) {
		int x = read () , y = read () , z = read ();
		add ( x , y , z );
	}
	Spfa ( 1 );
	for ( int i = 1 ; i <= n ; i++ ) 
		printf ( "%d%c" , dis[i] == 0x3f3f3f3f ? 2147483647 : dis[i] , i == n ? '\n' : ' ' );
	return 0;
}

單源最短路 (無負權邊)

在題目明確說沒有負權邊的情況下,跑堆優化的\(Dijkstra\)一定是最穩的
其實程式碼長得都差不多

#include <queue>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#define F(i,a,b) for ( int i = a ; i <= b ; i++ )
#define MP std::make_pair
#define se second
#define fi first

typedef std::pair < int , int > pll;
const int N = 1e5 + 10; 
const int M = 4e5 + 20;

std::priority_queue < pll , std::vector < pll > , std::greater < pll > > qu;
int n , m , s , t;
struct Edge {
	int to;
	int data;
	int next;
}e[M];
int head[N] , dis[N];
bool inque[N];

inline int read () {
	int s = 0 , w = 1;
	char ch = getchar ();
	while ( ch > '9' || ch < '0' ) { if ( ch == '-' ) w = -1; ch = getchar ();}
	while ( ch >= '0' && ch <= '9' ) { s = s * 10 + ch - '0'; ch = getchar ();}
	return s * w;
}
void add ( int x , int y , int z ) {
	e[++t].to = y;
	e[t].data = z;
	e[t].next = head[x];
	head[x] = t;
	return;
}
inline void Heap_Dijkstra ( int x ) {
	memset ( dis , 0x3f3f3f3f , sizeof ( dis ) );
	dis[x] = 0;
	qu.push ( MP ( dis[x] , x ) );
	while ( !qu.empty () ) {
		int j = qu.top ().se;
		qu.pop ();
		if ( inque[j] ) 
		    continue;
		inque[j] = 1;
		for ( int i = head[j] ; i ; i = e[i].next ) {
			int k = e[i].to;
			if ( dis[k] > dis[j] + e[i].data ) {
				dis[k] = dis[j] + e[i].data;
				qu.push ( MP ( dis[k] , k ) );
			}
		}
	}
	return;
}

int main ( void ) {
	n = read ();
	m = read ();
	s = read ();
	F ( i , 1 , m ) {
		int x = read () , y = read () , z = read ();
		add ( x , y , z );
	}
	Heap_Dijkstra ( s );
	F ( i , 1 , n ) 
		printf ( "%d " , dis[i] );
	return 0;
}

割點

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>

inline int read () {
	int s = 0 , w = 1;
	char ch = getchar ();
	while ( ch > '9' || ch < '0' ) { if ( ch == '-' ) w = -1; ch = getchar ();}
	while ( ch >= '0' && ch <= '9' ) { s = s * 10 + ch - '0'; ch = getchar ();}
	return s * w;
}

const int N = 20005;
const int M = 200005;

int n , m , t , idx;
int head[N] , dfn[N] , low[N];
bool flag[N];

struct Edge {
	int to;
	int next;
} e[M];

inline void add ( int x , int y ) {
	e[++t].to = y;
	e[t].next = head[x];
	head[x] = t;
	return;
}
void Tarjan ( int cur , int father ) {
	int child = 0;
	dfn[cur] = low[cur] = ++idx;
	for ( int i = head[cur] ; i ; i = e[i].next ) {
		int j = e[i].to;
		if ( !dfn[j] ) {
			Tarjan ( j , father );
			low[cur] = std :: min ( low[cur] , low[j] );
			if ( low[j] >= dfn[cur] && cur != father ) 
				flag[cur] = 1;
			if ( cur == father )
				child++;
		}
		low[cur] = std :: min ( low[cur] , dfn[j] );
	}
	if ( father == cur && child >= 2 ) 
		flag[cur] = 1;
	return;
}

int main ( void ) {
	n = read () , m = read ();
	for ( int i = 1 ; i <= m ; i++ ) {
		int x = read () , y = read ();
		add ( x , y );
		add ( y , x );
	} 
	for ( int i = 1 ; i <= n ; i++ ) 
		if ( !dfn[i] ) 
			Tarjan ( i , i );
	for ( int i = 1 ; i <= n ; i++ ) 
		if ( flag[i] ) 
			printf ( "%d\n" , i );
	return 0;
} 

線性求逆元

const int HA = 998244353;
int main ( void ) {
	inv[1] = 1;
	for ( int i = 2 ; i <= n ; i++ ) 
		inv[i] = ( HA - HA / i ) * inv[HA % i]  % HA;
	return 0;
}

樹狀陣列區間修改區間求和

#include <bits/stdc++.h>
#define ll long long
#define MP make_pair
#define F(i,a,b) for(int i=a;i<=b;i++)
#define D(i,a,b) for(int i=a;i>=b;i--)
#define PB push_back

inline int read () {
	int s = 0 , w = 1;
	char ch = getchar ();
	while ( ch > '9' || ch < '0' ) { if ( ch == '-' ) w = -1; ch = getchar ();}
	while ( ch >= '0' && ch <= '9' ) { s = s * 10 + ch - '0'; ch = getchar ();}
	return s * w;
}

const int N = 100005;

int n , m;
ll num[N];

inline int lowbit ( int x ) {
	return x & -x;
} 

struct Tree {
	ll tree[N];
	
	inline void add ( ll x , int pos ) {
		while ( pos <= n ) {
			tree[pos] += x;
			pos += lowbit ( pos );
		}
		return;
	} 
	
	inline ll query ( int pos ) {
		ll res = 0;
		while ( pos ) {
			res += tree[pos];
			pos -= lowbit ( pos );
		}
		return res;
	}
	
}t[2];

int main ( void ) {
	n = read () , m = read ();
	for ( int i = 1 ; i <= n ; i++ ) {
		num[i] = read ();
		t[0].add ( num[i] - num[i - 1] , i );
		t[1].add ( ( num[i] - num[i - 1] ) * i , i );
	}
	for ( int i = 1 ; i <= m ; i++ ) {
		int opts = read () , l = read () , r = read ();
		if ( opts == 1 ) {
			ll val = read ();
			t[0].add ( val , l );
			t[0].add ( -val , r + 1 );
			t[1].add ( val * l , l );
			t[1].add ( -val * ( r + 1 ) , r + 1 );
		}
		else if ( opts == 2 ) {
			ll ValR = ( r + 1 ) * t[0].query ( r ) - t[1].query ( r );
			ll ValL = ( l ) * t[0].query ( l - 1 ) - t[1].query ( l - 1 );
			printf ( "%lld\n" , ValR - ValL );
		}
	}
	return 0;
}

矩陣快速冪(求fib數列)

	struct Matx {
		ll rec[3][3];
	} ms , lab , ans , st;

	Matx operator * ( Matx x , Matx y ) {
		Matx tmp;
		for ( ll i = 0 ; i < 3 ; i++ ) for ( ll j = 0 ; j < 3 ; j++ ) tmp.rec[i][j] = 0;
			for ( ll i = 1 ; i <= 2 ; i++ ) 
				for ( ll j = 1 ; j <= 2 ; j++ ) 		
					for ( ll k = 1 ; k <= 2 ; k++ ) 
					tmp.rec[i][j] = ( tmp.rec[i][j] + ( 1ll * x.rec[i][k] * y.rec[k][j] ) % HA ) % HA;
		return tmp;
	}

	int main ( void ) {	
		m = read ();
		while ( m-- ) { 
			std :: cin >> s;
			ll nn = read ();
			for ( ll i = 0 ; i < 3 ; i++ ) for ( ll j = 0 ; j < 3 ; j++ ) ans.rec[i][j] = 0;
			ms.rec[1][1] = 0 , ms.rec[1][2] = 1 , ms.rec[2][1] = 1 , ms.rec[2][2] = 1;
			lab.rec[1][1] = 1 , lab.rec[1][2] = 0 , lab.rec[2][1] = 0 , lab.rec[2][2] = 1;
			st.rec[1][1] = 1 , st.rec[1][2] = 1;
			ll yy = nn;
			while ( yy ) {
				if ( yy & 1ll ) 
					lab = lab * ms;
				ms = ms * ms;
				yy >>= 1ll;
			}
			for ( ll i = 1 ; i <= 1 ; i++ ) 
				for ( ll j = 1 ; j <= 2 ; j++ ) 
					for ( ll k = 1 ; k <= 2 ; k++ ) 
						ans.rec[i][j] = ( ans.rec[i][j] + ( 1ll * st.rec[i][k] * lab.rec[k][j] ) % HA ) % HA;	
			writeln ( ans.rec[1][1] );
			puts ( "" );																
		}
		return 0;																						
	}

擴充套件歐幾里得(同餘方程)

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define int long long

using namespace std;

int a , b , x , y;

void exgcd ( int a , int b ) {
	if ( !b ) {
		x = 1;
		y = 0;
		return;
	}
	exgcd ( b , a % b );
	int tx = x;
	x = y;
	y = tx - a / b * y;
	return; 
}

signed main ( void ) {
	cin >> a >> b;
	exgcd ( a , b );
	x = ( x % b + b ) % b;
	cout << x << endl;
	return 0;
}

樹的直徑

#include <bits/stdc++.h>
using namespace std;

const int N = 10005;

int n , t;
int head[N] , f[N][3];
struct Edge {
	int to;
	int date;
	int next;
}e[N << 2];

inline void add ( int x , int y , int z ) {
	e[++t].to = y;
	e[t].date = z;
	e[t].next = head[x];
	head[x] = t;
	return;
} 
void dfs1 ( int x , int fa ) {
	for ( int i = head[x] ; i ; i = e[i].next ) {
		int y = e[i].to;
		if ( y == fa ) 
			continue;
		dfs1 ( y , x );
		int temp = f[y][0] + e[i].date;
		if ( temp >= f[x][0] ) {
			f[x][1] = f[x][0];
			f[x][0] = temp;
		}
		else if ( temp > f[x][1] ) 
			f[x][1] = temp;
	}
	return;
}
void dfs2 ( int x , int fa ) {
	for ( int i = head[x] ; i ; i = e[i].next ) {
		int y = e[i].to;
		if ( f[x][0] == f[y][0] + e[i].date )
			f[y][2] = max ( f[x][2] , f[x][1] ) + e[i].date;
		else 
			f[y][2] = max ( f[x][2] , f[x][0] ) + e[i].date;
		dfs2 ( y , x );
	}
	return;
}
int main ( void ) {
	while ( scanf ( "%d" , &n ) != EOF ) {
		t = 0;
		memset ( f , 0 , sizeof ( f ) );
		memset ( head , 0 , sizeof ( head ) );
		for ( int i = 2 ; i <= n ; i++ ) {
			int x , y;
			scanf ( "%d%d" , &x , &y );
			add ( x , i , y );
		}
		dfs1 ( 1 , 0 );
		dfs2 ( 1 , 0 );
		for ( int i = 1 ; i <= n ; i++ ) 
			printf ( "%d\n" , max ( f[i][0] , f[i][2] ) );
	}
	return 0;
}

最小圓覆蓋

#include<cstdio> 
#include<cmath>
#include<algorithm>

using namespace std;

#define N 1000001

struct Point
{
    double x,y;
}e[N]; 

struct Circle
{
    Point c;
    double r;
}a;

double dis(Point a,Point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

Circle mid(Point a,Point b)
{
    Circle o;
    o.c.x=(a.x+b.x)/2;
    o.c.y=(a.y+b.y)/2;
    o.r=dis(a,b)/2;
    return o;
}

Circle work(Point A,Point B,Point C)
{
    double a=B.x-A.x;
    double b=C.x-A.x;
    double c=B.y-A.y;
    double d=C.y-A.y;
    double e=(B.x*B.x-A.x*A.x+B.y*B.y-A.y*A.y)/2;
    double f=(C.x*C.x-A.x*A.x+C.y*C.y-A.y*A.y)/2;
    Circle cc;
    double m=a*d-b*c;
    if(abs(m)<1e-4)
    {
        double dis1=dis(A,C);
        double dis2=dis(B,C);
        if(dis1>dis2) return mid(A,C);
        return mid(B,C);
    }
    cc.c.x=(e*d-c*f)/m;
    cc.c.y=(a*f-b*e)/m;
    cc.r=dis(cc.c,A);
    return cc;
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%lf%lf",&e[i].x,&e[i].y);
    random_shuffle(e+1,e+n+1);
    a.c=e[1];
    for(int i=2;i<=n;++i)
        if(dis(e[i],a.c)>a.r) 
        {
            a.c=e[i];
            a.r=0;
            for(int j=1;j<i;++j)
                if(dis(e[j],a.c)>a.r)
                {
                    a=mid(e[i],e[j]);
                    for(int k=1;k<j;++k)
                    {
                        if(dis(e[k],a.c)>a.r)
                            a=work(e[i],e[j],e[k]);
                    //    printf("i=%d j=%d k=%d : %.2lf %.2lf %.2lf \n",i,j,k,a.c.x,a.c.y,a.r);
                    } 
                }
        }
    printf("%.2lf %.2lf %.2lf",a.c.x,a.c.y,a.r);
}

多項式

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=4e6+10;
struct POLY{
	long double Pi=acos(-1);
	int P=998244353;
	int G=3;
	int limit,rev[N],hpa[N],hpb[N],hpc[N],hpd[N],hpe[N],hpp[N];
	struct CP {
	    long double x, y;
        CP conj () {
			return CP ( x , -y );
		}
	    CP ( long double xx = 0 , long double yy = 0 ) {
			x = xx;
			y = yy;
		};
	    CP operator + ( const CP &tmp ) const {
	    	return CP ( x + tmp.x , y + tmp.y );
		};
		CP operator - ( const CP &tmp ) const {
			return CP ( x - tmp.x , y - tmp.y );
		};
		CP operator * ( const CP &tmp ) const {
			return CP ( x * tmp.x - y * tmp.y , x * tmp.y + y * tmp.x );
		};
		bool operator == ( const CP &tmp ) const {
			if ( x == tmp.x && y == tmp.y ) 
				return true;
			else return false;
		}
	};
	void FFT ( CP *A , int bord , int type ) {
		for ( int i = 0 ; i < bord ; i++ ) 
			if ( i < rev[i] ) 
				swap ( A[i] , A[rev[i]] );
		for ( int  mid = 1 ; mid < bord ; mid <<= 1 ) {
			CP Wn ( cos ( Pi / mid ) , type * sin ( Pi / mid ) );
			for ( int R = mid << 1 , j = 0 ; j < bord ; j += R ) {
				CP w ( 1 , 0 );
				for ( int k = 0 ; k < mid ; k++ ) {
					CP x = A[j + k] , y = w * A[j + mid + k];
					A[j + k] = x + y;
					A[j + mid + k] = x - y;
					w = w * Wn;
				}
			}
		}
		return;
	}
	inline void init ( int n ) {
	    limit = 1;
	    int t = 0;
	    while ( limit < n ) {
	        limit <<= 1;
	        t++;
	    }
	    for ( int i = 1 ; i < limit ; i++ ) 
	        rev[i] = ( rev[i >> 1] >> 1 ) | ( i & 1 ) << ( t - 1 );
	    return;
	}
//Calc the convolution of f(x) and g(x) whose {lenf+leng==len}  Use FFT
	inline void fmul ( CP *F , CP *G , int len ) {
		init ( len );
		FFT ( F , limit , 1 );
		FFT ( G , limit , 1 );
		for( int i = 0 ; i < limit ; i++ ) 
			F[i] = F[i] * G[i];
		FFT ( F , limit , -1 );
		return;
	} 
	inline int ksm ( int x , int y ) {
	    int ret = 1;
	    while ( y ) {
	        if ( y & 1 ) 
	            ret = 1ll * ret * x % P;
	        x = 1ll * x * x % P;
	        y >>= 1;
	    }
	    return ret % P;
	}
	inline void NTT ( int * A , int limit , int tp ) {
	    for ( int i = 0 ; i < limit ; i++ ) 
	        if ( i < rev[i] ) 
	            swap ( A[i] , A[rev[i]] );
	    for ( int m = 1 ; m < limit ; m <<= 1 ) {
	        int Wn = ksm ( G , ( P - 1 ) / ( m << 1 ) );
	        for ( int j = 0 ; j < limit ; j += m << 1 ) {
	            int w = 1 , x , y;
	            for ( int k = 0 ; k < m ; k++ ) {
	                x = A[j + k] % P;
	                y = w * A[j + k + m] % P;
	                A[j + k] = ( x + y ) % P;
	                A[j + k + m] = ( x - y + P ) % P;
	                w = 1ll * w * Wn % P;
	            }
	        }
	    }
	    if ( tp == -1 ) {
	        reverse ( A + 1 , A + limit );
	        int inv = ksm ( limit , P - 2 );
	        for ( int i = 0 ; i < limit ; i++ ) 
	            A[i] = 1ll * A[i] * inv % P;
	    }
	    return;
	}
//Calc the convolution of f(x) and g(x) whose {lenf+leng==len} Use NTT
	inline void mul ( int *f , int *g , int len ) {
	    init ( len );
	    NTT ( f , limit , 1 );
	    NTT ( g , limit , 1 );
	    for ( int i = 0 ; i < limit ; i++ ) 
	        f[i] = 1ll * f[i] * g[i] % P;
	    NTT ( f , limit , -1 );
	    return;
	}
//Calc 1/f(x) and the answer in g[]
	void getinv ( int *f , int *g , int len ) {
	    if ( len == 1 ) {
	        g[0] = ksm ( f[0] , P - 2 );
	        return;
	    }
	    getinv ( f , g , len + 1 >> 1 );
	    init ( len << 1 );
	    for ( int i = 0 ; i < len ; i++ ) 
	        hpc[i] = f[i];
	    for ( int i = len ; i < limit ; i++ ) 
	        hpc[i] = 0;
	    NTT ( hpc , limit , 1 );
	    NTT ( g , limit , 1 );
	    for ( int i = 0 ; i < limit ; i++ ) 
	        g[i] = ( 1ll * 2 - 1ll * g[i] * hpc[i] % P + P ) % P * g[i] % P;
	    NTT ( g , limit , -1 );
	    for ( int i = len ; i < limit ; i++ ) 
	        g[i] = 0;
	    return;
	}
	void getdev ( int *f , int *g , int len ) {
	    for ( int i = 1 ; i < len ; i++ ) 
	        g[i - 1] = 1ll * i * f[i] % P;
	    g[len - 1] = 0;
	    return;
	}
	void getinvdev ( int *f , int *g , int len ) {
	    for ( int i = 1 ; i < len ; i++ ) 
	        g[i] = 1ll * f[i - 1] * ksm ( i , P - 2 ) % P;
	    g[0] = 0;
	    return;
	}
//Calc ln{f(x)} and the answer in ans[]
	void getln ( int *f , int *ans , int len ) {
	    memset ( hpa , 0 , sizeof ( hpa ) );
	    memset ( hpb , 0 , sizeof ( hpb ) );
	    getdev ( f , hpa , len );
	    getinv ( f , hpb , len );
	    mul ( hpa , hpb , len << 1 );
	    getinvdev ( hpa , ans , len );
	    return;
	}
//Calc e^{f(x)} and the answer in ans[]
	void getexp ( int *f , int *ans , int len ) {
    	if ( len == 1ll ) {
    	    ans[0] = 1;
    	    return;
    	}
    	getexp ( f , ans , len + 1 >> 1 );
    	init ( len << 1 );
    	for ( int i = 0 ; i < ( len << 1 ) ; i++ ) 
    	    hpd[i] = hpe[i] = 0;
    	getln ( ans , hpd , len );
    	for ( int i = 0 ; i < len ; i++ ) 
    	    hpe[i] = f[i];
    	NTT ( ans , limit , 1 );
    	NTT ( hpd , limit , 1 );
    	NTT ( hpe , limit , 1 );
    	for ( int i = 0 ; i < limit ; i++ ) 
    	    ans[i] = 1ll * ( 1 - hpd[i] + hpe[i] + P ) * ans[i] % P;
    	NTT( ans , limit , -1 );
    	for ( int i = len ; i < limit ; i++ )
    	    ans[i] = 0; 
    	return;
	}
//Cala f(x)^k whose length is len and the answer in ans[]
	void getksm ( int *f , int *ans , int k , int len ) {
    	getln ( f , hpp , len );
    	for ( int i = 0 ; i < limit ; i++ ) 
        	hpp[i] = 1ll *hpp[i] * k % P;
    	getexp ( hpp , ans , len ); 
    	for ( int i = 0 ; i < limit ; i++ ) 
        	hpp[i] = 0;
    	return;
	} 
// Calc f(x)^{\frac{1}{prime}} whose length is len and the answer in ans[]
	void getsqrt ( int *f , int *ans , int len ) {
    	int inv = ksm ( 2 , P - 2 );
    	getln ( f , hpp , len );
    	for ( int i = 0 ; i < limit ; i++ ) 
    	    hpp[i] = hpp[i] * inv % P;
    	getexp ( hpp , ans , len );
    	for ( int i = 0 ; i < limit ; i++ ) 
        	hpp[i] = 0;
   		return;
	} 
	CP ca[N],cc[N],cb[N],cd[N];
	void mmul(int *f,int *g,int *ans,int len,int p){
		init(len);
		len=limit;
		for(int i=0;i<len;i++){
			ca[i].x=(f[i]>>15),ca[i].y=(f[i]&32767);
			cc[i].x=(g[i]>>15),cc[i].y=(g[i]&32767);
		}
		FFT(ca,len,1);
		FFT(cc,len,1);
		for(int i=0;i<len;i++)
			cb[i]=ca[len-i].conj();
		cb[0]=ca[0].conj();
		for(int i=0;i<len;i++)
			cd[i]=cc[len-i].conj();
		cd[0]=cc[0].conj();
		for(int i=0;i<len;i++){
			CP
				AA=(ca[i]+cb[i])*CP(0.5,0),
				BB=(ca[i]-cb[i])*CP(0,-0.5),
				CC=(cc[i]+cd[i])*CP(0.5,0),
				DD=(cc[i]-cd[i])*CP(0,-0.5);
			ca[i]=AA*CC+CP(0,1)*(AA*DD+CC*BB);
			cb[i]=BB*DD; 
		}
		FFT(ca,len,-1);
		FFT(cb,len,-1);
		for(int i=0;i<len;i++){
			int 
				AA=(long long)(ca[i].x/len+0.5)%p,
				BB=(long long)(ca[i].y/len+0.5)%p,
				CC=(long long)(cb[i].x/len+0.5)%p;
			ans[i]=((1ll*AA*(1<<30)+1ll*BB*(1<<15)+CC)%p+p)%p; 
		} 
	}
}Poly;
signed main ( void ) {
    
    return 0;
}

擴充套件歐幾里德求逆元(可模非質數)

int ex_gcd(int a,int b,int &x,int &y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}
	int ans=ex_gcd(b,a%b,y,x);
	y-=a/b*x;
	return ans;
}
 
int inverse(int a,int n){
    int d,x,y;
    d=ex_gcd(a,n,x,y);
    return d==1?(x+n)%n:-1;
}

算幾

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const double PI=acos(-1);
#define PointType long long
struct Node{
	PointType x,y;
	PointType operator * (const Node &p) const {
		return x*p.x+y*p.y;			
	}
	PointType operator ^ (const Node &p) const {
		return x*p.y-y*p.x;
	} 
	Node operator - (const Node &p) const {
		return (Node){x-p.x,y-p.y};
	}
	bool operator < (const Node &p) const {
		if(x!=p.x)
			return x<p.x;
		else 
			return y<p.y;
	}
}p[N],h[N];
bool used[N];
int st[N],top,n,cnt;# 
PointType TranS(Node x,Node y,Node z){
	return (y-x)^(z-x);
}
PointType lentq(Node x,Node y){
	return (y.x-x.x)*(y.x-x.x)+(y.y-x.y)*(y.y-x.y);
}
PointType lent(Node x,Node y){
	return sqrt((y.x-x.x)*(y.x-x.x)+(y.y-x.y)*(y.y-x.y));
}
void Andrew(){
	sort(p+1,p+1+n);
	st[++top]=1;
	used[1]=1;
	for(int i=2;i<=n;i++){
		while(top>=2&&((p[st[top]]-p[st[top-1]])^(p[i]-p[st[top]]))<=0)
			used[st[top--]]=0;
		used[i]=1;
		st[++top]=i;
	}
	int ret=top;
	for(int i=n-1;i>=1;i--){
		while(top>ret&&((p[st[top]]-p[st[top-1]])^(p[i]-p[st[top]]))<=0)
			used[st[top--]]=0;
		used[i]=1;
		st[++top]=i;
	}
	for(int i=1;i<=top;i++)
		h[i]=p[st[i]];
	return;
}
PointType RollStuckShell(){
	if(n==2)
		return lentq(p[1],p[2]);
	int j=3;
	PointType ans=0;
	for(int i=1;i<top;i++){
		int nxt=(j==top-1)?1:j+1;
		while(TranS(h[i],h[i+1],h[j])<TranS(h[i],h[i+1],h[nxt])){
			j=nxt;
			nxt=(j==top-1)?1:j+1;
		}
		ans=max(ans,max(lentq(h[i],h[j]),lentq(h[i+1],h[j]))); 
	}
	return ans;		
} 
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%lld%lld",&p[i].x,&p[i].y);
	Andrew();
	cout<<RollStuckShell()<<endl;
	return 0;
} 

自適應辛普森積分

函式斂散性證明:
\(f(x)\)\([a,+\infty)\)上有\(f(x)\ge0\)
如果存在常數\(p>1\)(是大於不是大於等於)使得\(\lim\limits_{x\to+\infty}x^pf(x)=c<+\infty\),那麼\(\int_{a}^{+\infty}f(x)\,dx\)收斂
如果\(\lim\limits_{x\to+\infty}xf(x)=d>0\),那麼\(f(x)\)發散。

\(a\)\(f(x)\)的無窮間斷點,\(f(x)\)\((a,b]\)上有\(f(x)\ge0\)
如果存在常數\(0<p<1\)使得\(\lim \limits_{x \to a^{+}}(x-a)^p f(x)=d>0\),那麼\(\int_a^bf(x) \, dx\)收斂
如果\(\lim \limits_{x \to a^{+}}(x-a)f(x)=d>0\),那麼\(\int_a^b f(x) \, dx\)發散。

\(b\)\(f(x)\)的無窮間斷點,\(f(x)\)\([a,b)\)上有\(f(x)\ge0\)
如果存在常數\(0<p<1\)使得\(\lim \limits_{x \to b^{-}}(b-x)^p f(x)=d>0\),那麼\(\int_a^bf(x) \, dx\)收斂
如果\(\lim \limits_{x \to b^{-}}(b-x)f(x)=d>0\),那麼\(\int_a^b f(x) \, dx\)發散。

#include<bits/stdc++.h>
using namespace std;
double a;
inline double f(double x){//calc f(x)
	return pow(x,a/x-x);//can change by title
}
//
double Simpon(double l,double r){
	double mid=(l+r)/2;
	return (r-l)*(f(l)+f(r)+4*f(mid))/6; 
}
double asr(double l,double r,double eqs,double ans,double step){
	double mid=(l+r)/2;
	double fl=Simpon(l,mid),fr=Simpon(mid,r);
	if(abs(fl+fr-ans)<=15*eqs&&step<0)
		return fl+fr+(fl+fr-ans)/15;
	else return asr(l,mid,eqs/2,fl,step-1)+asr(mid,r,eqs/2,fr,step-1);	
}
double calc(double l,double r,double eps){
	return asr(l,r,eps,Simpon(l,r),12);
}
// temp
int main(){
	cin>>a;
	if(a<0)
		return puts("orz"),0;
	else 
		return printf("%.5lf\n",calc(1e-8,20,1e-8)),0;
	return 0;
} 
因為知道了自己是多麼的菜,所以才要更加努力去追求那個永遠也不可能實現的夢想