等比数列三角形 (数论 + 黄金分割点)+ JOISC 2016 Day3 T3 「电报」(基环树 + 拓扑排序)
文章目錄
- T1:等比數列三角形
- 題目
- 題解
- 代碼實現
- T2:電報
- 題目
- 題解
- 代碼實現
T1:等比數列三角形
題目
求三邊都是 ≤n 的整數,且成等比數列的三角形個數
注意三角形面積不能為 0
注意 oeis 中未收錄此數列,所以并不需要去搜了
輸入格式
一行一個整數 n
輸出格式
一行一個整數表示答案
樣例
樣例輸入1
9
樣例輸出1
10
樣例解釋1
除去 9 個等邊三角形,還有 {4,6,9} 。
樣例輸入2
100
樣例輸出2
133
數據范圍與提示
一共有 4 個子任務,對于每一個子任務,你只有通過了該子任務的所有測試點,才能獲得此子任務的分數
有 10pts,保證 n≤10
有 20pts,保證 n≤105
有 20pts,保證 n≤105
有 50pts,保證 n≤1012
對于所有數據,有1≤ n≤1012
題解
注意{4,6,9},{6,4,9},{9,6,4}算同一個三角形,所以不用管順序
設三條邊從小到大分別為a,ak,ak2a,ak,ak^2a,ak,ak2(kkk為公比且為正整數)
所以1≤k1≤k1≤k
就然要構成三角形,必然要滿足
a+ak>ak2=>1+k>k2=>k2?k?1<0a+ak>ak^2=>1+k>k^2=>k^2-k-1<0a+ak>ak2=>1+k>k2=>k2?k?1<0
解得k<√5+12k<\frac{√5+1}{2}k<2√5+1?
綜上k∈[1,√5+12)k∈[1,\frac{√5+1}{2})k∈[1,2√5+1?)
接下來令k=pqk=\frac{p}{q}k=qp?(q,pq,pq,p互質),最大邊就表示為a?p2q2a*\frac{p^2}{q^2}a?q2p2?
最大邊≤n≤n≤n,故此q≤√nq≤√nq≤√n
因為q=pkq=\frac{p}{k}q=kp?,那么
- 當kkk取最大時,qqq取最小,把k=√5+12k=\frac{√5+1}{2}k=2√5+1?帶入就解出了qqq的最小值,
但因為k取不到這個開區間,q的這個最小值也是一個開區間 - 當k取最小時,qqq取最大,這是滿足q=pq=pq=p,qqq的這個最大值是一個閉區間
綜上q∈(p?2√5+1,p]q∈(p*\frac{2}{√5+1},p]q∈(p?√5+12?,p],在這里有個轉化思想,把ppp代換成qqq,得到q∈(q?2√5+1,q]q∈(q*\frac{2}{√5+1},q]q∈(q?√5+12?,q]
我們就可以枚舉p∈[1,√n]p∈[1,√n]p∈[1,√n],算出此時q的可取值個數
注意:其實理解成枚舉qqq也是說得通的
當這樣統計完后,會出現一個問題
{2,3,6},{4,6,9}\{2,3,6\},\{4,6,9\}{2,3,6},{4,6,9}這種公比為32\frac{3}{2}23?的三角形,會被重復計算進公比為64\frac{6}{4}46?
所以我們需要把這些排除掉,這也是為什么上面推導的時候pq\frac{p}{q}qp?要保證互質
這里就可以用類似埃篩的方法,把xxx的因數里面算過的三角形減掉
要正著減,如果倒著,公比為128\frac{12}{8}812?會先減掉公比為96\frac{9}{6}69?而這里面還包含著32\frac{3}{2}23?
會導致32\frac{3}{2}23?被重復減掉
代碼實現
#include <cstdio> #include <cmath> using namespace std; #define LL long long #define MAXN 1000005 LL n, result; int ok[MAXN]; int main() {scanf ( "%lld", &n );int sqt = sqrt ( n );for ( int i = 1;i <= sqt;i ++ ) {int t = i * ( 2 / ( sqrt ( 5 ) + 1 ) );ok[i] = i - t;}for ( LL i = 1;i <= sqt;i ++ )for ( LL j = i << 1;j <= sqt;j += i )ok[j] -= ok[i];for ( LL i = 1;i * i <= n;i ++ )result += ( n / ( i * i ) ) * ok[i];printf ( "%lld", result );return 0; }T2:電報
題目
給出 n 個點,每個點的出度均為 1,給出這 n 個點初始指向的點A[i] ,和改變這個點指向的目標所需要的價值 C[i]。
求讓所有點強連通的最小花費。
輸入格式
第一行輸入一個數 n 表示點的個數。
之后的 n 行每行兩個數 A[i],C[i] 表示第 i 個點指向第 A[i] 個點,更改該點指向的點花費為 C[i]。
輸出格式
共一行,為讓所有點強連通的最小花費。
樣例
樣例輸入 1
4
2 2
1 4
1 3
3 1
樣例輸出 1
4
樣例解釋 1
很顯然,把 1–>2 的這條邊改成 (花費 4)的情況下構成強連通分量花費最小。
樣例輸入 2
4
2 2
1 6
1 3
3 1
樣例輸出 2
5
樣例解釋 2
很顯然把 1–>2 的這條邊改成 1–>4 花費 2,把 3–>1 的這條邊改成 3–>2 花費 3 的情況下構成強連通分量花費最小,總花費為 5。
樣例輸入 3
4
2 2
1 3
4 2
3 3
樣例輸出 3
4
樣例輸入 4
3
2 1
3 1
1 1
樣例輸出 4
0
題解
首先為了能變成強連通,樹上的點彼此之間需要破掉,先不動環上的點
如圖中:7,8,97,8,97,8,9和10,11,12,1310,11,12,1310,11,12,13就必須破掉,破成一條鏈
要么把7→87\rightarrow87→8破掉,要么把7→97\rightarrow97→9破掉,然后讓7?8?97-8-97?8?9連成一條鏈
可以用拓撲排序找到不是環上的點,然后把這棵樹破成鏈,如果本身是鏈就不進行操作
圖就變成多個環和多棵樹的形態
顯然,環彼此之間是相互獨立的,就可以掃一次先處理出所有的環
我們在上面進行樹上破成鏈的時候,把環延伸的鏈或樹也一起破掉
如圖中:就把6→76\rightarrow76→7和6→106\rightarrow106→10都給破掉
接著如果變成強連通,環與環之間必須相互有路去連通
就是復活環與之外連的某一條邊
意味著我們要把環破掉一條邊和外界相連
那么這個時候,對于環上的最佳答案點肯定滿足把它與它父親在環上的邊破掉,然后把它與自己延伸的鏈的點進行相連的操作花費最小
破環就是自己的CCC值,與鏈上的點保留一條邊,就是找鏈上點的CCC的最大值
如圖中:我們要把6→16\rightarrow16→1破掉,復活6→76\rightarrow76→7或者6→106\rightarrow106→10任意一條邊
而且必須復活至少一條,這樣才能讓環與外面進行連通
但是如果圖上有多個點的復活值是負數,那么肯定是全選上,使答案變得更小
在上面破 環與鏈的邊 的時候,我們就記錄最大值的CCC,復活的時候,肯定復活這一條邊,其他邊的消耗遠小于這一條邊破掉的消耗
最后我們來解釋一下代碼的一些地方,旁邊的小姐姐問了我很久
-
為什么是建反圖:
想一想,如果我們建正圖,每個點都只會有一個指向點,即每個點的vector里面都只有111個點,怎么破鏈,復活等以上的操作呢?
換言之,每個點要知道自己的后繼,才能知道破哪些邊 -
flag||tot>1的問題,我們要知道
當只有環的時候,如果環是多個,也需要破掉,使所有環彼此強連通
當只有一個環的時候,如果環上有鏈也需要破掉,不然環上的點無法走到鏈上的點
所以這里是取或,當且僅當原圖本身就是一個環才不用考慮復活
代碼實現
這里定義isCircle[i]
1:表示這個點不在環上(PS:可能誤導了許多親故 )
2:表示這個點在環上且已經經過了破樹或破鏈處理
0:表示這個點在環上但等待被處理
總結
以上是生活随笔為你收集整理的等比数列三角形 (数论 + 黄金分割点)+ JOISC 2016 Day3 T3 「电报」(基环树 + 拓扑排序)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NT6 HDD Installer是什么
- 下一篇: Star Way To Heaven (