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...