《生化危機》官方釋出“保護傘”公司主題腕錶
整理一下常用的板子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;
}
因為知道了自己是多麼的菜,所以才要更加努力去追求那個永遠也不可能實現的夢想