感谢鹏神,因为好多都是借鉴他的昂!
球冠、球缺(图自百度百科):
球冠体积:S=2πR^2(1 - sinθ)=2πRH
球缺体积:V=(π/3)*(3R-H)*H^2
快速读入与快速输出:
1 inline int read(){
2 int x=0,d=1;
3 char c=getchar();
4 while((c>'9'||c<'0')&&c!='-')c=getchar();
5 if(c=='-')d=-1;
6 while(c>='0'&&c<='9'){
7 x=x*10+c-'0';
8 c=getchar();
9 }
10 return x*d;
11 }
12
13 inline void write(int num){
14 if(num>9)write(num/10);
15 putchar(num%10+'0');
16 }
组合数打表:
1 void init(){
2 for(int i=0;i<=500;++i){
3 for(int j=0;j<=i;++j){
4 C[i][j]=(i==0||j==0)?1:(C[i-1][j]+C[i-1][j-1]);
5 }
6 }
7 }
预处理阶乘以及其逆元(QP是快速幂)、并计算组合数C(n,m):
1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4
5 const int maxn=1e6 + 35;
6 const int mod=1e9+7;
7
8 ll A[maxn+5],AA[maxn+5]; //A是阶乘数组,AA是阶乘逆元数组
9
10 ll QP(ll a,ll n){
11 ll ans = 1 ,tmp = a;
12 while(n){
13 if(n&1)ans = ans * tmp % mod;
14 tmp = tmp * tmp % mod;;
15 n >>= 1;
16 }
17 return ans;
18 }
19
20 void init(){
21 A[0]=1;
22 for(int i=1;i<=maxn;++i)A[i]=A[i-1]*i%mod;
23 AA[maxn]=QP(A[maxn],mod-2);
24 for(int i=maxn;i>=1;--i)AA[i-1]=AA[i]*i%mod;
25 }
26
27 ll C(int n,int m){
28 return A[n] * AA[n-m] % mod * AA[m] % mod;
29 }
内联汇编快速乘法:
1 inline ll mulmod(ll x, ll y, ll mod)
2 {
3 ll ans=0;
4 __asm__("movq %1,%%rax\n imulq %2\n idivq %3\n":"=d"(ans):"m"(x),"m"(y),"m"(mod):"%rax");
5 return ans;
6 }
约瑟夫环问题:
约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解。
1 #include <iostream>
2 #include <list>
3 using std::cout;
4 using std::endl;
5 using std::cin;
6 using std::list;
7
8 int main(){
9 int total = 0;
10 cout << "Please input total number of people : ";
11 cin >> total;
12 int number = 0;
13 cout << "Please input selected number : ";
14 cin >> number;
15 /* If number = 3
16 * f(1) = 0
17 * f(2) = 1 = (f(1) + 3) % 2
18 * f(3) = 1 = (f(2) + 3) % 3
19 * f(4) = 0 = (f(3) + 3) % 4
20 * f(5) = 3 = (f(4) + 3) % 5
21 * ...
22 * f(n) = x = (f(n-1) + 3) % n
23 * */
24 int last = 0; // f(1) = 0
25 for(int i = 2; i <= total; ++i){
26 last = (last + number) % i;
27 }
28 cout << "The last one is : " << last + 1 << endl;
29 return 0;
30 }
五边形数(数字拆分):
题意:问一个数n能被拆分成多少种方法,且每一种方法里数字重复个数不能超过k(等于k)。
分析递推式为:
1 #include<iostream>
2 #include<string.h>
3 #include<stdio.h>
4 using namespace std;
5
6 const int N=100005;
7 const int MOD=1000000007;
8
9 int dp[N];
10
11 void Init(){
12 dp[0]=1;
13 for(int i=1;i<N;i++){
14 dp[i]=0;
15 for(int j=1;;j++){
16 int t=(3*j-1)*j/2;
17 if(t>i)break;
18 int tt=dp[i-t];
19 if(t+j<=i)tt=(tt+dp[i-t-j])%MOD;
20 if(j&1)dp[i]=(dp[i]+tt)%MOD;
21 else dp[i]=(dp[i]-tt+MOD)%MOD;
22 }
23 }
24 }
25
26 int Work(int n,int k){
27 int ans=dp[n];
28 for(int i=1;;i++){
29 int t=k*i*(3*i-1)/2;
30 if(t>n)break;
31 int tt=dp[n-t];
32 if(t+i*k<=n)tt=(tt+dp[n-t-i*k])%MOD;
33 if(i&1)ans=(ans-tt+MOD)%MOD;
34 else ans=(ans+tt)%MOD;
35 }
36 return ans;
37 }
38
39 int main(){
40 Init();
41 int n,k,t;
42 scanf("%d",&t);
43 while(t--){
44 scanf("%d%d",&n,&k);
45 printf("%d\n",Work(n,k));
46 }
47 return 0;
48 }
幂次求和:
Σ(i,1,n)(i)=n*(n+1)/2= 1/2 * n2 + 1/2 * n
Σ(i,1,n)(i2)=n*(n+1)*(2n+1)/6= 1/3 * n3 + 1/2 * n2 +1/6 * n
Σ(i,1,n)(i3)= (n*(n+1)/2)2 = 1/4 * n4 + 1/2 * n3 +1/4 * n2
Σ(i,1,n)(i4)= n*(n+1)*(2n+1)*(3x2+3x-1)/30 = 1/5 * n5 + 1/2 * n4 + 1/3 * n3 - 1/30 * n
Σ(i,1,n)(i4)= n2 *(n+1)*(2n3+4n2+n-1)/12
海伦公式:
S=sqrt(p*(p-a)*(p-b)*(p-c));
p=(a+b+c)/2.0;
用四边长a、b、c、d表达园内接四边形面积的婆罗摩笈多公式:
S=sqrt((p-a)*(p-b)*(p-c)*(p-d));
p=(a+b+c+d)/2.0;
三角形外接圆半径公式:
R=a*b*c/(4*S)=a*b*c/sqrt((a+b+c)*(a+b-c)*(a-b+c)*(-a+b+c));
三角形内切圆半径公式:
r=(1/2)*sqrt((a+b-c)*(a-b+c)*(-a+b+c)/(a+b+c));
a,b,c分别为三角形的边长。