2020牛客寒假演算法基礎集訓營1

2022-10-11 07:18:08 字數 4131 閱讀 5327

honoka最近在研究三角形計數問題。

她認為,滿足以下三個條件的三角形是「好三角形」。

1.三角形的三個頂點均為格點,即橫座標和縱座標均為整數。

2.三角形的面積為 。

3.三角形至少有一條邊和 軸或 軸平行。

honoka想知道,在平面中選取乙個大小為 的矩形格點陣,可以找到多少個不同的「好三角形」?由於答案可能過大,請對 取模。

輸入描述:

兩個正整數和( 2\ ≤n,m≤10^9)(2 ≤n,m≤10 ^9)

輸出描述:

面積為1的格點三角形的數量,對 10^9+7 取模的結果。

面積為二的三角形 只能是 底1高2 或者底2高1 分別以橫縱座標軸標軸方向為底 計算共多少情況 需要注意的是 直角三角形會有重複,我計算了底邊橫向的所有情況

底邊縱向的刪去所有直角三角形 以底邊橫向為例

加入底邊長 1 那麼在一條橫線上 可以有(m-1)個底邊每個底邊朝乙個方向可以有多少個頂點呢,是m個。只要到底邊距離為2就可以了,已經有一條邊平行座標軸了完全符合條件。 而每條線的三角形都有上下兩個方向所以(但邊緣的兩個都只有乙個)所以 再乘(2*n-2) 然後該底邊是2的情況 只需將(m-1)改為(m-2)就行了

(長度為m的邊上只能有(m-2)個長度為2的子邊)

計算底邊縱向時 和剛才死的分析思路是一樣 就是要減去直角三角形 減多少個呢

以每個底邊為例 底邊的兩端點對應的頂點所構成的就是直角三角形了,每個底邊減二就可以了 注意別爆 ll

具體看**:

#include

using

namespace std;

typedef

long

long ll;

const

int n=

100010

,mod=

1e9+7;

ll cnt,n,m;

intmain()

return0;

}

b 題 求期望就不說了 c沒做(應該是最難的一道了)

d 排序後就知道缺那個數了

e. 求x的因子個數 只用遍歷到 sqrt(x)就行了 所以最多也就是1e6的級別 不會超時 所以一直迭代就好了

#include

using

namespace std;

typedef

long

long ll;

const

int n=

100010

,mod=

1e9+7;

int d[8]

[2]=

; ll a,b,n,m;

intf

(ll x)

return cnt;

}int

main()

else n=x;

}}

f 求樹上路徑最多隻經過乙個黑點的數量 所以黑點可能出現在端點或者中間

如果出現在端點 那麼路徑上其他點只能是白色 所以路徑的數量就是黑點周圍的白點的數量(與其他黑色節點之間的所有白節點)

如果出想在中間 那麼白色節點就要經過這個黑節點與其他白節點相連(起點與終點必須位於黑點的不同的連通分支中) 求每個連通分支的與其他黑點之間的白點數量

再把任意兩個分支的數量相乘就可以了

#include

using

namespace std;

typedef

long

long ll;

const

int n=

200010

,mod=

1e9+7;

int n,h[n]

,e[n]

,ne[n]

,idx;

char s[n]

;vector<

int> ve;

void

add(

int a,

int b)

ll ans,sum[n]

;int

dfs(

int x,

int pre)

else res+

=dfs

(y,x);}

return res;

}int

main()

for(

int i=

1;i<=n;i++)if

(s[i]

=='b'

) cout<}

g 求含k個相同字母的最小子串長度

這種求最值的問題很容易就會想到二分了,那怎麼二分呢

首先肯定是需要二分長度了 那麼怎麼快速的判斷是否合適呢

只要子串長度大於等於k個某字母的起始區間長度,那這個長度就是合適的

首先預處理字串 因為只有26個字母,所以完全可以將每個字母出現的位置存下來

而且同一字母 位置的陣列內是單增的 只需要遍歷看 判斷長度是否合適就行了

#include

using

namespace std;

typedef

long

long ll;

const

int n=

200010

,mod=

1e9+7;

int d[8]

[2]=

; ll a,b,n,k;

char s[n]

;vector<

int> ve[30]

;bool

check

(int x)

return0;

}int

main()

if(l>=n) cout<<-1

;else cout<1; 二分的是不滿足這個性質的最大長度

}

h.這道題還是可以二分,也是二分長度

把一段子串變成一樣字元的最小操作=min(0的數量,1的數量);

怎麼求一段字串的0和1的數量 對整段字串求字首和 然後就可以求區間和了,一段子串的區間和就是 1的數量了(沒有對0計數)0的數量就是區間長度-區間和

#include

using

namespace std;

typedef

long

long ll;

const

int n=

200010

,mod=

1e9+7;

int d[8]

[2]=

; ll a,b,n,k;

char s[n]

;int sum[n]

;bool

check

(int x)

return0;

}int

main()

cout<}

i . 不同的單詞有不同的分數,每個字母只能用一次,問最大分數是多少

這題非常適合dp,不管a,b,c的大小關係如何 每次dp去最大值就好,虧我想了那麼種情況兩個多小時也沒做對,我太菜了。dp得好好複習複習了

#include

using

namespace std;

typedef

long

long ll;

const

int n=

300010

,mod=

1e9+7;

string str;

ll a,b,c,n;

ll ans,dp[n]

;int

main()

if(i>=

5&&str.

substr

(i-5,6

)=="niconi"

) dp[i]

=max

(dp[i]

,dp[i-5]

+b);

if(i>=

9&&str.

substr

(i-9,10

)=="niconiconi"

) dp[i]

=max

(dp[i]

,dp[i-9]

+c);

} cout<;return0;

}

2020牛客寒假演算法基礎集訓營

長期更新,補完為止 2 g 判正誤 題意 t組資料。判斷a d b e c f是否等於g。1e9 a,b,c,g 1e9,0 d,e,f 1e9。保證不會出現指數和底數同為 0 的情況。思路 硬算會tle或mle。快速冪取模,為了增加過題概率,多取幾個模數判斷。includeusing namesp...

2020牛客寒假演算法基礎集訓營1

找規律,推公式 三角形個數為2 m n m n m 1 n 1 2 m n mn m 1 n 1 2 m n mn m 1 n 1 include include include include using namespace std typedef long long ll const int m...

2020牛客寒假演算法基礎集訓營1

h題 突然發現h題可以用好多種方法做的。方法一 雙指標,維護乙個修改次數小於等於k的區間 include using namespace std typedef long long ll const int mod 1e9 7 const int n 1e5 5 const int inf 0x3f...