数论
int cnt,prime[MAXN+1],mi[MAXN+1],vis[MAXN+1]; //cnt表示素数个数 //prime存放每个素数 //mi存放每个数的最小素数因子 void getprime() { cnt = 0; memset(prime,0,sizeof(prime)); for(int i = 2;i <= MAXN;i++) { if(!vis[i]) { prime[++cnt] = i; mi[i] = i; } for(int j = 1;j <= cnt && (long long)i*prime[j] <= MAXN;j++) { vis[prime[j]*i] = 1; mi[prime[j]*i] = prime[j]; if(!(i%prime[j])) break; } } } int cnt2,notprime2[1000005],prime2[1000005]; //区间l,r之间的素数 void getprime2(int l,int r) { cnt2 = 0; memset(notprime2,0,sizeof(notprime2)); if(l < 2) l = 2; for(int i = 1;i <= cnt && (long long)prime[i]*prime[i] <= r;i++) { int t = l/prime[i]; if(l%prime[i]) t++; if(t == 1) t = 2; for(int j = t;(long long)j*prime[i] <= r;j++) { if((long long)j*prime[i] >= l) notprime2[j*prime[i]-l] = 1; } } for(int i = 0;i <= r-l;i++) { if(!notprime2[i]) prime2[++cnt2] = i+l; } }
long long factor[105][2]; //返回素因子个数 //factor[i][0]表示第i个素因子,factor[i][1]表示第i个素因子的个数 int getfac(long long x) { int cnt = 0; for(int i = 1;(long long)prime[i]*prime[i] <= x;i++) { if(x%prime[i] == 0) { factor[++cnt][0] = prime[i]; while(x%prime[i] == 0) { factor[cnt][1]++; x /= prime[i]; } } } if(x != 1) { factor[++cnt][0] = x; factor[cnt][1] = 1; } return cnt; }
long long qmul(long long a,long long b,long long c) { long long ans = 0; a = a%c; b = b%c; while(b) { if(b%2) { ans += a; if(ans > c) ans -= c; } a = a+a; if(a > c) a -= c; b /= 2; } return ans; }
long long qpower(long long a, long long b, long long c) { long long ans = 1; a = a%c; while(b) { if(b%2) ans = ans*a%c; a = a*a%c; b /= 2; } return ans; }
string mul(string a,string b) { int arr[200],len = a.length()+b.length(); memset(arr,0,sizeof(arr)); reverse(a.begin(),a.end()); reverse(b.begin(),b.end()); for(int i = 0;i < a.length();i++) { for(int j = 0;j < b.length();j++) arr[i+j] += (a[i]-'0')*(b[j]-'0'); } for(int i = 0;i < len;i++) { arr[i+1] += arr[i]/10; arr[i] %= 10; } string ans = string(len,'0'); for(int i = 0;i < len;i++) ans[i] += arr[i]; reverse(ans.begin(),ans.end()); cout << ans << endl; return ans; } string strpow(string x,int b) { string ans = "1"; while(b) { if(b%2) ans = mul(ans,x); x = mul(x,x); b /= 2; } return ans; }
struct matrix { long long m[2][2]; }; matrix one = { 1,0, 0,1 }; matrix mul(matrix a, matrix b) { matrix tmp; for(int i = 0; i < 2;i++) { for(int j = 0; j < 2;j++) { tmp.m[i][j] = 0; for(int k = 0; k < 2;k++) tmp.m[i][j] = (tmp.m[i][j]+a.m[i][k]*b.m[k][j])%MOD; } } return tmp; } matrix maqower(matrix a,int b) { matrix ans = one; while(b) { if(b%2) ans = mul(ans,a); a = mul(a,a); b /= 2; } return ans; }
long long qmul(long long a,long long b,long long c) { long long ans = 0; a = a%c; b = b%c; while(b) { if(b%2) { ans += a; if(ans > c) ans -= c; } a = a+a; if(a > c) a -= c; b /= 2; } return ans; } long long qpower(long long a,long long b,long long c) { long long ans = 1; a = a%c; while(b) { if(b%2) ans = qmul(ans,a,c); a = qmul(a,a,c); b /= 2; } return ans; } //用a来检验n是否为素数 //是素数返回1,不是返回0 bool check(long long a,long long n,long long x,long long t) { long long ans = qpower(a,x,n); if(ans == 1 || ans == n-1) return 1; while(t--) { ans = qmul(ans,ans,n); if(ans == n-1) return 1; } return 0; } //判断n是否为素数 //是素数返回1,不是返回0 bool miller_rabin(long long n) { if(n < 2) return 0; if(n == 2) return 1; if(n%2 == 0) return 0; long long x = n-1; long long t = 0; while(x%2 == 0) { x /= 2; t++; } srand(time(0)); for(int i = 1;i <= 10;i++) { long long a = rand()%(n-1)+1; if(!check(a,n,x,t)) return 0; } return 1; }
long long factor[105]; int cnt; long long gcd(long long a,long long b) { return b?gcd(b,a%b):a; } long long pollard_rho(long long n,long long c) { long long i = 1,k = 2; srand(time(0)); long long x = rand()%(n-2)+1,y = x; while(1) { i++; x = (qmul(x,x,n)+c)%n; long long d = gcd(y-x,n); if(1 < d && d < n) return d; if(x == y) return n; if(i == k) { y = x; k *= 2; } } } //求n的质因数,k设为107 void findfac(long long n,int k) { if(n == 1) return; if(miller_rabin(n)) { factor[++cnt] = n; return; } long long p = n; int c = k; while(p >= n) p = pollard_rho(p,c--); findfac(p,k); findfac(n/p,k); }
LL gcd(LL x,LL y) //最大公约数 { return y?gcd(y,x%y):x; } LL lcm(LL x,LL y) //最小公倍数 { return x*y/gcd(x,y); }
//lcm(C(n,0), C(n,1),…, C(n,n)) = lcm(1,2,3,…n+1)/(n+1) //计算lcm(1,2,3,…n) const int N=100000007; int visit[N/32+50]; unsigned int data[5800000]; int prime[5800000],np=0; void Prime() //筛素数,数组从0开始 { prime[0] = data[0] = 2; np = 1; for(int i = 3;i < N;i += 2) { if(!(visit[i/32]&(1<<((i/2)%16)))) { prime[np] = i; data[np] = data[np-1]*i; np++; for(int j = 3*i;j < N;j += 2*i) visit[j/32] |= (1<<((j/2)%16)); } } } long long Deal(int n) { int p = upper_bound(prime,prime+np,n)-prime-1; long long ans = data[p]; for (int i = 0;i < np && prime[i]*prime[i] <= n;i++) { int mul = prime[i],tmp = prime[i] * prime[i]; ; while (tmp/mul == prime[i] && tmp <= n) { tmp *= prime[i]; mul *= prime[i]; } ans = ans*(mul/prime[i])%MOD; } return ans; }
欧拉函数:小于N且与N互质的数的个数(包括1)。
对于一个正整数N的素数幂分解N = P1^q1*P2^q2*...*Pn^qn。
φ(N)=N*(1-1/P1)*(1-1/P2)*...*(1-1/Pn)。
//分解质因数 int euler(int n) { int ans = n; for(int i = 1;i <= cnt;i++) ans = ans/factor[i][0]*(factor[i][0]-1); } long long euler(long long n) { long long ans = 1; for(int i = 2;(long long)i*i <= n;i++) { if(n%i == 0) { n /= i; ans *= i-1; while(n%i == 0) { n /= i; ans *= i; } } } if(n > 1) ans *= n-1; return ans; }
int cnt,phi[N+10],prime[N+10],vis[N+10]; //同时得到欧拉函数和素数表 void geteuler() { memset(vis,0,sizeof(vis)); phi[1] = 1; cnt = 0; for(int i = 2;i <= N;i++) { if(!vis[i]) { prime[++cnt] = i; phi[i] = i-1; } for(int j = 1;j <= cnt;j++) { if((long long)i*prime[j] > N) break; vis[i*prime[j]] = 1; if(i%prime[j] == 0) { phi[i*prime[j]] = phi[i]*prime[j]; break; } else phi[i*prime[j]] = phi[i]*(prime[j]-1); } } }
lucas定理:
A、B是非负整数,p是质数。AB写成p进制:A=a[n]a[n-1]...a[0],B=b[n]b[n-1]...b[0]。
则组合数C(A,B)与C(a[n],b[n])*C(a[n-1],b[n-1])*...*C(a[0],b[0]) modp同余。
即:Lucas(n,m,p)=c(n%p,m%p)*Lucas(n/p,m/p,p) 。
//用与n,m很大,MOD不是很大的情况 long long qmod(long long a,long long b,long long c) { long long ans = 1; a = a%c; while(b) { if(b%2) ans = (ans*a)%c; a = (a*a)%c; b /= 2; } return ans; } long long c(long long m,long long n) { if(m < n) return 0; if(m == n) return 1; if(n > m-n) n = m-n; long long mm = 1,nn = 1; for(long long i = 0;i < n;i++) { mm = mm*(m-i)%MOD; nn = nn*(n-i)%MOD; } return mm*qmod(nn,MOD-2,MOD)%MOD; } long long lucas(long long m,long long n) { long long ans = 1; while(m && n && ans) { ans = ans%MOD*c(m%MOD,n%MOD)%MOD; n /= MOD; m /= MOD; } return ans; }
long long inv(long long a,long long MOD) { if(!a) return 0; long long b = MOD,x = 0,y = 0; e_gcd(a,b,x,y); x = ((x%b)+b)%b; if(!x) x += b; return x; } long long mul(long long n,long long pi,long long pk) { if(!n) return 1; long long ans=1; for(long long i = 2;i <= pk;i++) { if(i%pi) ans = ans*i%pk; } ans = qpower(ans,n/pk,pk); for(long long i = 2;i <= n%pk;i++) { if(i%pi) ans = ans*i%pk; } return ans*mul(n/pi,pi,pk)%pk; } long long C(long long n,long long m,long long MOD,long long pi,long long pk) { if(m > n) return 0; long long a = mul(n,pi,pk),b = mul(m,pi,pk),c = mul(n-m,pi,pk),k = 0,ans = 0; for(long long i = n;i;i /= pi) k += i/pi; for(long long i = m;i;i /= pi) k -= i/pi; for(long long i = n-m;i;i /= pi) k -= i/pi; ans = a*inv(b,pk)%pk*inv(c,pk)%pk*qpower(pi,k,pk)%pk; return ans*(MOD/pk)%MOD*inv(MOD/pk,pk)%MOD; } long long lucas(long long n,long long m,long long MOD) { long long ans = 0,x = MOD; for(long long i = 2;i*i <= x;i++) { if(x%i == 0) { long long t = 1; while(x%i == 0) { t *= i; x /= i; } ans = (ans+C(n,m,MOD,i,t))%MOD; } } if(x > 1) ans = (ans+C(n,m,MOD,x,x))%MOD; return ans; }
费马小定理:假如p是素数,且a与p互质,那么a^(p-1) = 1 (mod p)。
费马大定理:当整数n>2时,关于 x,y,z的方程x^n+y^n=z^n没有正整数解。
欧拉定理:若n,a为正整数,且n,a互质,则:a^(phi(n)) = 1(mod n)
可得a^b%p = a^(b%phi(p))%p
另外,a,b不互质且b<phi(n)时,有 a^b%p = a^(b%phi(p)+phi(p))%p
逆元:ax = 1(mod m)的x值(0 < a < m)。
当p是质数的时候 a/x mod p == a*x^(p-2) mod p 。
当p不是质数的时候a/x mod p == a*x^(phi(p)-1) mod p。
//a,m互质 long long inv(long long a,long long m) { return qmod(a,m-2,m); }
//a < m且a,m互质 long long inv(long long a,long long m) { if(a == 1) return 1; return inv(m%a,m)*(m-m/a)%m; }
//a,m互质 //扩展欧几里德 long long e_gcd(long long a,long long b,long long &x,long long &y) { if(!b) { x = 1; y = 0; return a; } long long d = e_gcd(b,a%b,y,x); y -= a/b*x; return d; } long long inv(long long a,long long m) { long long x,y; long long gcd = e_gcd(a,m,x,y); if(gcd == 1) return (x%m+m)%m; return -1; }
//求解方程组x%m = a,x的最小值 //无解返回-1 long long e_gcd(long long a,long long b,long long &x,long long &y) { if(!b) { x = 1; y = 0; return a; } long long d = e_gcd(b,a%b,y,x); y -= a/b*x; return d; } long long solve(long long *m,long long *a,long long n) { long long M = m[1],A = a[1],x,y; for(int i = 2;i <= n;i++) { long long d = e_gcd(M,m[i],x,y); if((a[i]-A)%d) return -1; x = (a[i]-A)/d*x%(m[i]/d); A += x*M; M = M/d*m[i]; A %= M; } if(A < 0) A += M; return A; }
//浮点型只有唯一解时可计算 //返回0表示无解 #define eps 1e-9 double a[N][N],x[N]; //左边矩阵和右边值,结果存在x数组内 int Gauss(int equ,int var) //方程个数和未知数个数 { for(int row = 0,col = 0;col < var&&row < equ;col++,row++) { int max_r=row; for(int i = row+1;i < equ;i++) { if(fabs(a[i][col])-fabs(a[max_r][col]) > eps) max_r=i; } if(fabs(a[max_r][col]) < eps) return 0; if(max_r != row) { for(int j = 0;j <= var;j++) swap(a[row][j],a[max_r][j]); } for(int i = row+1;i < equ;i++) { if(fabs(a[i][col]) < eps) continue; double t = -a[i][col]/a[row][col]; for(int j = col;j <= var;j++) a[i][j] += t*a[row][j]; } } for(int i = var-1;i >= 0;i--) //计算唯一解。 { double t = 0; for(int j = i+1;j < var;j++) t += a[i][j]*x[j]; x[i] = (a[i][var]-t)/a[i][i]; } return 1; }
#include<bits/stdc++.h> using namespace std; //POJ1681 //有equ个方程,var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var. int equ,var; int a[250][250]; //增广矩阵 int x[250]; //解集 int free_x[250]; //标记是否不确定的变元 int free_num; //不确定变元个数 int n; char s[30]; //-1表示无解,0表示唯一解,大于0表示无穷解,并返回自由变元的个数) void init() { memset(a,0,sizeof(a)); memset(x,0,sizeof(x)); equ = n*n; var = n*n; for(int i = 0;i < n;i++) { for(int j = 0;j < n;j++) { int t = i*n+j; a[t][t] = 1; if(i > 0) a[(i-1)*n+j][t] = 1; if(i < n-1) a[(i+1)*n+j][t] = 1; if(j > 0) a[i*n+j-1][t] = 1; if(j < n-1) a[i*n+j+1][t] = 1; } } } void Debug() { for(int i = 0;i < equ;i++) { for(int j = 0;j < var+1;j++) cout << a[i][j] << " "; cout << endl; } cout << endl; } int Gauss() { int max_r,col,k; free_num = 0; for(k = 0,col = 0;k < equ && col < var;k++,col++) { max_r = k; for(int i = k+1;i < equ;i++) { if(abs(a[i][col]) > abs(a[max_r][col])) max_r = i; } if(max_r != k) { for(int i = col;i < var+1;i++) swap(a[k][i],a[max_r][i]); } if(a[k][col] == 0) { k--; free_x[free_num++] = col; continue; } for(int i = k+1;i < equ;i++) { if(a[i][col] == 0) continue; for(int j = col;j < var+1;j++) a[i][j] ^= a[k][j]; } } for(int i = k;i < equ;i++) { if(a[i][col] != 0) return -1; } return var-k; } void solve() { int t = Gauss(); if(t == -1) printf("inf\n"); else { int ans = INT_MAX,tot = (1<<t); for(int i = 0;i < tot;i++) { int cnt = 0; for(int j = 0;j < t;j++) { if(i&(1<<j)) { x[free_x[j]] = 1; cnt++; } else x[free_x[j]] = 0; } for(int j = var-t-1;j >= 0;j--) { int t = a[j][var]; for(int k = j+1;k < var;k++) { if(a[j][k]) t ^= x[k]; } x[j] = t; cnt += x[j]; } ans = min(ans,cnt); } printf("%d\n",ans); } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); init(); for(int i = 0;i < n;i++) { scanf("%s",s); for(int j = 0;j < n;j++) { if(s[j] == 'y') a[i*n+j][n*n] = 0; else a[i*n+j][n*n] = 1; } } solve(); } return 0; }
int a[MAXN][MAXN]; //增广矩阵 int x[MAXN]; //解集 bool free_x[MAXN]; //标记是否是不确定的变元 int gcd(int a,int b) { return b?gcd(b,a%b):a; } int lcm(int a,int b) { return a/gcd(a,b)*b; } //-1表示无解,0表示唯一解,大于0表示无穷解,并返回自由变元的个数) //有equ个方程,var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var. int Gauss(int equ,int var) { int i,j,k; int max_r;// 当前这列绝对值最大的行. int col;//当前处理的列 int ta,tb; int LCM; int temp; int free_x_num; int free_index; for(int i = 0;i <= var;i++) { x[i]=0; free_x[i]=true; } col=0; for(k = 0;k < equ && col < var;k++,col++) { max_r=k; for(i = k+1;i < equ;i++) { if(abs(a[i][col]) > abs(a[max_r][col])) max_r=i; } if(max_r != k) { for(j = k;j < var+1;j++) swap(a[k][j],a[max_r][j]); } if(a[k][col] == 0) { k--; continue; } for(i = k+1;i < equ;i++) { if(a[i][col] != 0) { LCM = lcm(abs(a[i][col]),abs(a[k][col])); ta = LCM/abs(a[i][col]); tb = LCM/abs(a[k][col]); if(a[i][col]*a[k][col] < 0) tb = -tb; for(j = col;j < var+1;j++) { a[i][j] = ((a[i][j]*ta-a[k][j]*tb)%7+7)%7; } } } } for(i = k; i < equ; i++) { if (a[i][col] != 0) return -1; } if(k < var) { for(i = k-1;i >= 0;i--) { free_x_num = 0; for(j = 0;j < var;j++) { if (a[i][j] != 0 && free_x[j]) free_x_num++,free_index = j; } if(free_x_num > 1) continue; temp = a[i][var]; for(j = 0;j < var;j++) { if(a[i][j] != 0 && j != free_index) temp -= a[i][j]*x[j]%7; temp = (temp%7+7)%7; } x[free_index] = (temp/a[i][free_index])%7; free_x[free_index] = 0; } return var-k; } for(i = var-1;i >= 0;i--) { temp = a[i][var]; for (j = i + 1;j < var;j++) { if(a[i][j] != 0) temp -= a[i][j]*x[j]; temp = (temp%7+7)%7; } while(temp%a[i][i] != 0) temp += 7; x[i] =(temp/a[i][i])%7; } return 0; }
#include<bits/stdc++.h> #define N 262145 #define PI acos(-1) using namespace std; typedef complex<double> C; int n,m; C a[N],b[N]; int gi() { int res = 0,fh = 1; char ch = getchar(); while((ch > '9' || ch < '0') && ch != '-') ch = getchar(); if(ch == '-') { fh=-1; ch=getchar(); } while(ch >= '0' && ch <= '9') { res = res*10+ch-'0'; ch=getchar(); } return fh*res; } void fft(C *a,int n,int f) { if(n == 1) return; C wn(cos(2.0*PI/n),sin(f*2.0*PI/n)),w(1,0),t,a0[n>>1],a1[n>>1]; for(int i = 0;i < n>>1;i++) { a0[i] = a[i<<1]; a1[i] = a[i<<1|1]; } fft(a0,n>>1,f); fft(a1,n>>1,f); for(int i = 0;i < n>>1;i++,w *= wn) { t = w*a1[i]; a[i] = a0[i]+t; a[i+(n>>1)] = a0[i]-t; } } int main() { n = gi(); m = gi(); for(int i = 0;i <= n;i++) a[i]=gi(); for(int i = 0;i <= m;i++) b[i]=gi(); m += n; for(n = 1;n <= m;n *= 2); fft(a,n,1); fft(b,n,1); for(int i = 0;i <= n;i++) a[i] *= b[i]; fft(a,n,-1); for(int i = 0;i <= m;i++) printf("%d ",int(a[i].real()/n+0.5)); return 0; }
#include<bits/stdc++.h> #define N 262145 #define PI acos(-1) using namespace std; typedef complex<double> C; int n,m,L,R[N]; C a[N],b[N]; int gi() { int res = 0,fh = 1; char ch = getchar(); while((ch > '9' || ch < '0') && ch != '-') ch = getchar(); if(ch == '-') { fh=-1; ch=getchar(); } while(ch >= '0' && ch <= '9') { res = res*10+ch-'0'; ch=getchar(); } return fh*res; } void fft(C *a,int f) { for(int i = 0;i < n;i++) { if(i < R[i]) swap(a[i],a[R[i]]); } for(int i = 1;i < n;i *= 2) { C wn(cos(PI/i),sin(f*PI/i)),x,y; for(int j = 0;j < n;j += i<<1) { C w(1,0); for(int k = 0;k < i;k++,w *= wn) { x = a[j+k]; y = w*a[j+i+k]; a[j+k] = x+y; a[j+i+k] = x-y; } } } } int main() { n = gi(); m = gi(); for(int i = 0;i <= n;i++) a[i] = gi(); for(int i = 0;i <= m;i++) b[i] = gi(); m += n; for(n = 1;n <= m;n *= 2) L++; for(int i = 0;i < n;i++) R[i] = (R[i>>1]>>1)|((i&1)<<(L-1)); fft(a,1); fft(b,1); for(int i = 0;i <= n;i++) a[i] *= b[i]; fft(a,-1); for(int i = 0;i <= m;i++) printf("%d ",int(a[i].real()/n+0.5)); return 0; }
//需要getprime,qpower,getfac,先调用getprime //计算1+p+p^2+````+p^n long long sum(long long p,long long n) { if(p == 0) return 0; if(n == 0) return 1; if(n%2) return (1+qpower(p,n/2+1,MOD))%MOD*sum(p,n/2)%MOD; else return ((1+qpower(p,n/2+1,MOD))%MOD*sum(p,n/2-1)+qpower(p,n/2,MOD)%MOD)%MOD; } //求a^b的约数和对MOD取模 long long solve(long long a,long long b) { int cnt = getfac(a); long long ans = 1; for(int i = 1;i <= cnt;i++) { ans *= sum(factor[i][0],b*factor[i][1])%MOD; ans %= MOD; } return ans; }
莫比乌斯反演:
#include<bits/stdc++.h> using namespace std; const int MAXN = 100000; bool check[MAXN+5]; int prime[MAXN+5],mu[MAXN+5],sum[MAXN+5]; //求莫比乌斯函数 void Moblus() { memset(check,0,sizeof(check)); mu[1] = 1; int cnt = 0; for(int i = 2;i <= MAXN;i++) { if(!check[i]) { prime[cnt++] = i; mu[i] = -1; } for(int j = 0;j < cnt && i*prime[j] <= MAXN;j++) { check[i*prime[j]] = 1; if(i%prime[j] == 0) { mu[i*prime[j]] = 0; break; } else mu[i*prime[j]] = -mu[i]; } } sum[0] = 0; for(int i = 1;i <= MAXN;i++) sum[i] = sum[i-1]+mu[i]; } //求[1,n],[1,m]内互质的数的对数 int solve(int n,int m) { int ans = 0; if(n > m) swap(n,m); for(int i = 1,last;i <= n;i = last+1) { last = min(n/(n/i),m/(m/i)); ans += (sum[last]-sum[i-1])*(n/i)*(m/i); } return ans; } int main() { Moblus(); int a,b,c,d,k,T; scanf("%d",&T); while(T--) { scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); a--; c--; a /= k; b /= k; c /= k; d /= k; printf("%d\n",solve(b,d)-solve(a,d)-solve(b,c)+solve(a,c)); } }
#include<bits/stdc++.h> using namespace std; int gcd(int a, int b ) { return b == 0?a:gcd(b,a%b); } long long qpower(long long a, long long b, long long c) { long long ans = 1; a = a%c; while(b) { if(b%2) ans = ans*a%c; a = a*a%c; b /= 2; } return ans; } long long e_gcd(long long a,long long b,long long &x,long long &y) { if(!b) { x = 1; y = 0; return a; } long long d = e_gcd(b,a%b,y,x); y -= a/b*x; return d; } int Inval(int a,int b,int n) { long long x, y, e; e_gcd(a,n,x,y); e = (long long)x*b%n; return e < 0?e+n:e; } //求A^x = B(mod C)(C可以为非素数) int BSGS(int A,int B,int C) { map<int,int> H; long long buf = 1%C,D = buf,K; int d = 0,tmp; for (int i = 0;i <= 100;buf = buf*A%C,i++) if(buf == B) return i; while((tmp = gcd(A,C)) != 1) { if(B % gcd(A,C)!= 0) return -1; d++; C /= tmp; B /= tmp; D =D*A/tmp%C; } H.clear(); int M = (int)ceil(sqrt(C)); buf = 1%C; for(int i = 0;i <= M;buf = buf*A%C,i++) { if(H.find((int)buf) == H.end()) H[(int)buf] = i; } K = qpower(A,M,C); for(int i = 0;i <= M;D = D*K%C,i++) { tmp = Inval((int)D,B,C); if(tmp >= 0 && H.find(tmp) != H.end()) return i*M+H[tmp]+d; } return -1; }
const double eps = 1e-6; // 三点simpson法。这里要求F是一个全局函数 double simpson(double a,double b) { double c = a+(b-a)/2; return (F(a)+4*F(c)+F(b))*(b-a)/6; } // 自适应Simpson公式(递归过程)。已知整个区间[a,b]上的三点simpson值A double asr(double a,double b,double eps,double A) { double c = a+(b-a)/2; double L = simpson(a,c),R = simpson(c,b); if(fabs(A-L-R) <= 15*eps) return L+R+(A-L-R)/15; return asr(a,c,eps/2,L)+asr(c,b,eps/2,R); } // 自适应Simpson公式(主过程) double asr(double a,double b,double eps) { return asr(a,b,eps,simpson(a,b)); }
康托展开:
X = an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!
其中,ai为当前未出现的元素中是排在第几个(从0开始)。
int f(vector<int> v) { int sum = 0; for(int i = 0;i < 8;i++) { int t = 0; for(int j = i+1;j < 8;j++) { if(v[i] > v[j]) t++; } sum += t*h[7-i]; } return sum; }
//f[]:可以取走的石子个数 //sg[]:0~n的SG函数值 //hash[]:mex{} int n,m,p,f[N],sg[N],hashh[N]; void getSG(int n) { memset(sg,0,sizeof(sg)); for(int i = 1;i <= n;i++) { memset(hashh,0,sizeof(hashh)); for(int j = 1;f[j] <= i;j++) hashh[sg[i-f[j]]] = 1; for(int j = 0;j <= n;j++) //求mes{}中未出现的最小的非负整数 { if(hashh[j] == 0) { sg[i] = j; break; } } } }
1. 若划分的多个整数可以相同 设dp[i][j]为将i划分为不大于j的划分数。 (1) 当i<j 时,i不能划分为大于i的数,dp[i][j]=dp[i][i]。 (2) 当i>j 时,可以根据划分中是否含有j分为两种情况。 若划分中含有j,划分方案数为dp[i-j][j]。 若划分数中不含j,相当于将i划分为不大于j-1的划分数,为dp[i][j-1]。 所以当i>j时,dp[i][j]=dp[i-j][j]+dp[i][j-1]。 (3) 当i=j 时,若划分中含有j只有一种情况,若划分中不含j相当于将i划分为不大于j-1的划分数。此时dp[i][j]=1+dp[i][j-1]。 2.将n划分为k个整数的划分数 dp[i][j]表示将i划分成j个正整数的划分数。 (1) 当i<j时,i不能划分成j个正整数,dp[i][j]=0。 (2) 当i=j时,只有一种情况,dp[i][j]=1。 (3) 当i>j时, 此时根据含1和不含1,故dp[i][j]=dp[i-1][j-1]+dp[i-j][j]。 3. 若划分的正整数必须不同 设dp[i][j]为将i划分为不超过j的不同整数的划分数。 (1) 当i<j时,i不能划分为大于i的数,所以dp[i][j]=dp[i][i]。 (2) 当i>j时,可以根据划分中是否含有j分为两种情况。 若划分中含有j,则其余的划分中最大只能是j-1,方案数为dp[i-j][j-1]。 若划分中不含j,相当于将i划分为不大于j-1的划分数,为dp[i][j-1]。 所以当i>j时dp[i][j]=dp[i-j][j-1]+dp[i][j-1]。 (3) 当i=j时,若划分中含有j只有一种情况,若划分中不含j相当于将i划分为不大于j-1的划分数。此时dp[i][j]=1+dp[i][j-1]。 4.将n划分为若干正奇数之和的划分数 设f[i][j]为将i划分为j个奇数之和的划分数,g[i][j]为将i划分为j个偶数之和的划分数。 使用截边法,将g[i][j]的j个划分都去掉1,可得g[i][j] = f[i-j][j]。 f[i][j]中有包含1的划分方案和不包含1的划分方案。 对于包含1的划分方案,可以将1的划分除去,转化为“将i-1划分为j-1个奇数之和的划分数”,即f[i-1][j-1]。 对于不包含1的划分方案,可以使用截边法对j个划分每一个都去掉一个1,转化为“将i-j划分为j个偶数之和的划分数”,即g[i-j][j]。 所以f[i][j]=f[i-1][j-1]+g[i-j][j]。 f[n][0]+f[n][1]+……+f[n][n]为将n划分为若干奇数的划分数。
Polya定理:设 G = {a1,a2,…,ag}是 N 个对象的置换群,用 M 种颜色给这 N 个对象着色,
则不同的着色 方案数为:|G|^(-1) * {M^c(a1) + M^c(a2) + … + M^c(ag)}。其中 c(ai)为置换 ai 的循环节数,( i = 1,2,…,g )。
设m是正整数,a是整数,若a模m的阶等于φ(m),则称a为模m的一个原根。
如果g是P的原根,那么g的(1...P-1)次幂mod P的结果一定互不相同。
如果g是P的原根,就是g^(P-1) = 1 (mod P)当且仅当指数为P-1的时候成立.(这里P是素数).
int n,a[35000],cnt = 0; LL qmod(LL a, LL b, LL c) { LL ans = 1; a = a%c; while(b) { if(b&1) ans = ans*a%c; b >>= 1; a = a*a%c; } return ans; } int main() { scanf("%d",&n); int endd = sqrt(n-1); for(int i = 2;i <= endd;i++) { if((n-1)%i == 0) a[++cnt] = i; } for(int i = 2;i <= n-1;i++) { int j; for(j = 1;j <= cnt;j++) { if(qmod(i,a[j],n) == 1 || qmod(i,(n-1)/a[j],n) == 1) break; } if(j == cnt+1) { printf("%d\n",i); return 0; } } }
卡特兰数 1, 2, 5, 14, 42
h(0) = 1,h(1) = 1 h(n) = h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2) h(n) = h(n-1)*(4*n-2)/(n+1) h(n) = C(2n,n)/(n+1) h(n) = C(2n,n)-C(2n,n-1) 1.n对括号正确匹配组成的字符串数。 2.一个栈(无穷大)的进栈序列为1,2,3,…,n,有多少个不同的出栈序列。 3.在一个凸多边形中,通过若干条互不相交的对角线,把这个多边形划分成了若干个三角形,求不同划分的方案数f(n)。 4.一位大城市的律师在她住所以北n个街区和以东n个街区处工作。 5.长度为 2n的 Dyck words的数量。 Dyck words是由 n个 X和 n个 Y组成的字符串,并且从左往右数, Y的数量不超过 X。 6.拥有 n+1 个叶子节点的二叉树的数量。例如 4个叶子节点的所有二叉树形态。 7.圆桌握手问题: 圆桌周围有 2n个人,他们两两握手,但没有交叉的方案数。
调和级数
f(n)≈ln(n)+C+1/2*n (n很大时)
C≈0.57721566490153286060651209