本原直角三角形及應用
本原直角三角形
本原直角三角形是指三邊長均為整數且兩兩互素的直角三角形
所有的直角三角形的三邊長一定是某個本原直角三角形的對應倍數
定義一
對於互質的一對奇偶性相異的數 m , n ( m > n > 0 ) m,n(m>n>0) m,n(m>n>0),得到唯一一組本原直角三角形,其三邊長度分別為 a = m 2 − n 2 , b = 2 n m , c = m ∗ m + n ∗ n a=m^2-n^2,b=2nm,c=m*m+n*n a=m2−n2,b=2nm,c=m∗m+n∗n
定義二
對於任意互質奇數 p , q ( p > q > 0 ) p,q(p>q>0) p,q(p>q>0),得到唯一一組本原直角三角形,其三邊長度分別為 a = ( p 2 − q 2 ) / 2 , b = p q , c = ( p 2 + q 2 ) / 2 a=(p^2-q^2)/2,b=pq,c=(p^2+q^2)/2 a=(p2−q2)/2,b=pq,c=(p2+q2)/2
定理
- 本原直角三角形的的兩條直角邊必須一個是奇數一個是 4 4 4的倍數的偶數,斜邊必為 4 4 4的倍數加一。周長和麵積必為偶數(實際上所有的直角三角形的周長面積也一定為偶數)
- 本原直角三角形的斜邊必為 4 4 4的倍數加一,但是不是所有的 4 4 4的倍數加一的數能構成本原直角三角形的斜邊,奇數 c c c且為 4 4 4的倍數加一能構成本原直角三角形的充要條件為能分解為一個奇數和一個偶數的平方和,即 c = k 2 + r 2 c=k^2+r^2 c=k2+r2,此時不難發現這就是二元二次不定方程的整數解問題。
應用
給定直角三角形周長 n n n求有多少個
因為所有的直角三角形都一定能找到本原直角三角形,又因為本原直角三角形的周長為 2 m 2 + 2 n m 2m^2+2nm 2m2+2nm,因此只需要列舉 m ∈ [ 2 , n ) m\in[2,\sqrt{n}) m∈[2,n)。然後記錄每種周長對應不同的本原直角三角形個數,那麼我們只需要對 n n n因數分解,然後累加每種因數對於的本原直角三角形個數。
下面因數分解步驟是先線性篩,然後常數時間質因數分解,最後常數時間搜尋; O ( ( n ) 2 ) = O ( n ) O((\sqrt{n})^2)=O(n) O((n)2)=O(n)時間複雜度預處理 g c d gcd gcd; O ( ( n ) 2 ) = O ( n ) O((\sqrt{n})^2)=O(n) O((n)2)=O(n)列舉每對 m , n m,n m,n。總體時間複雜度 O ( n ) O(n) O(n)。
int gcd[3510][3510];
int prime[maxn / 2], p[maxn], num[1005], pfac[1005], C[maxn];
vector<int> fac;
int cnt1, cnt2, tot;
void init() {
for (int i = 1; i <= 3500; i++) {
for (int j = 1; j <= 3500; j++) {
if (!gcd[i][j]) {
for (int k = 1; k * i <= 3500 && k * j <= 3500; k++)
gcd[k * i][k * j] = k;
}
}
}
int up = sqrt(maxn), xx = 0;
for (int m = 2; m < up; m++) {
for (int n = 1; n < m; n++) {
if (gcd[m][n] > 1) continue;
int sym = (n ^ m) & 1, cc = 2 * m * m + 2 * n * m;
if (sym && cc < maxn) {
C[cc]++;
}
}
}
}
void euler() {
cnt1 = 0;
for (int i = 1; i < maxn; i++) p[i] = i;
for (int i = 2; i < maxn; i++) {
if (p[i] == i) prime[++cnt1] = i;
for (int j = 1; j <= cnt1 && 1LL * i * prime[j] < maxn; j++) {
p[i * prime[j]] = prime[j];
if (i % prime[j] == 0) break;
}
}
}
void divide(int n) {
cnt2 = 0;
while (n != 1) {
pfac[++cnt2] = p[n];
n /= p[n];
}
sort(pfac + 1, pfac + 1 + cnt2);
tot = 1, num[tot] = 1;
for (int i = 2; i <= cnt2; i++) {
if (pfac[i] == pfac[i - 1]) {
num[tot]++;
} else {
num[++tot] = 1;
pfac[tot] = pfac[i];
}
}
}
void dfs(int d, ll cur = 1) {
if (d == tot + 1) {
fac.push_back(cur);
return;
}
for (int i = 0; i <= num[d]; i++) {
dfs(d + 1, cur);
cur *= pfac[d];
}
}
int solve(int n) {
//主函式初始化init(), euler();
divide(n);
fac.clear();
dfs(1, 1);
int ans = 0;
for (int i = 0; i < fac.size(); i++) {
ans += C[fac[i]];
}
return ans;
}
相關文章
- Webpack 下使用 web workers 及 基本原理 和 應用場景Web
- Flink基本原理與應用場景
- 【趣味設計模式系列】之【代理模式1--基本原理、實戰及框架應用】設計模式框架
- RabbitMQ的應用場景以及基本原理介紹MQ
- RabbitMQ 的應用場景以及基本原理介紹MQ
- 深度學習新星:GAN的基本原理、應用和走向深度學習
- React元件及應用React元件
- HDFS/MapReduce及應用
- zookeeper原理及應用
- EJB 部署及應用
- LNMP部署及應用LNMP
- Android應用及應用管理簡介Android
- 大資料彈性應用開發的八項基本原則大資料
- RPC基本原理及實現RPC
- 反射機制及應用反射
- 系統安全及應用
- xgboost原理及應用
- [轉]SSH原理及應用
- 華為防火牆及應用防火牆
- Sqlite 介紹及應用SQLite
- Java動態代理—框架中的應用場景和基本原理Java框架
- Java動態代理——框架中的應用場景和基本原理Java框架
- vxlan基本原理及裸搭過程
- 閉包的原理及應用
- Android Protobuf應用及原理Android
- Redux 原始碼剖析及應用Redux原始碼
- 單調棧理解及應用
- Catalan數計算及應用
- 應用根本原因分析降低醫院不安全事件發生率事件
- 【轉】設定Qt應用程式圖示及應用程式名QT
- 3128.直角三角形
- Lucene介紹及簡單應用
- ZooKeeper核心原理及應用場景
- WebSocket 簡介及應用例項Web
- RabbitMQ核心元件及應用場景MQ元件
- redis應用場景及例項Redis
- zigzag走線原理及應用
- Logistic 迴歸-原理及應用