題目大意:給你乙個n*m的矩陣,矩陣裡面的數值範圍為[1,1e9]。這個矩陣有乙個值,如果相鄰的多個數字是一樣的,那麼val += 他們的組合數,例如 1 1 1,那麼就是val就是6.
問最後這個矩陣是val是多少?
思路:我們固定右端點,先統計出上方有幾個和他數值相同的數字,並把這個定義成這個位置的高,然後每次往統計以這個點為右下角的端點數即可。然後暴力右下角就是o(n*n)
我們發現,如果要每次暴力相同的數字,那麼要知道前面有幾個數字的高度,然後o(n)的暴力一遍是可以的,但是這樣會tle
所以我們知道,如果高度是》=目前的h[i][j]的高度的,那麼我們就ans[i][j] += h[i][j] * (j - k +1),其中k為高度若是出現a[i][j] == a[i][k - 1],那麼我們就只需要ans[i][j] += ans[i][k - 1]即可
//view code看看會不會爆int!陣列會不會少了一維!
//取物問題一定要小心先手勝利的條件
#include using
namespace
std;
#pragma comment(linker,"/stack:102400000,102400000")
#define ll long long
#define all(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const
int maxn = 1000 + 5
;int
n, m;
inth[maxn][maxn], a[maxn][maxn], cnt[maxn][maxn];
intmain()
}ll res = 0
;
for (int i = 1; i <= n; i++)
else
else
break
; }
cnt[i][j] = h[i][j] * (j - p.se + 1
);
if (a[i][j] == a[i][p.se - 1]) cnt[i][j] += cnt[i][p.se - 1
]; res +=cnt[i][j];
que.push_back(p);}}
}printf(
"%lld\n
", res);
}return0;
}/*5493 3
1 2 1
1 1 1
1 1 1
ans = 25
4564
3 21 2
1 11 1
ans = 13
45609
3 22 1
1 11 1
ans = 13
*/
組合數學 序列統計
題解 生成乙個長度為1 n的序列,在l,r區間中選擇數字。那麼有m r l 1個數字可以選擇,每個數字選擇的次數加起來為n,所以這是明顯的插空法。為了讓每個數字都一定會被選一次,所以左右全部 1,接下裡就是利用公式合併再盧卡斯一下了。pragma gcc optimize 2 include def...
自主命題 奇組合數個數統計
對於給定的數字 n,l,r 求在 c n l,c n c n dots,c n r 中共有多少個奇數。行號 n 從0開始計數。特別地,我們規定 c 0 0 1 資料保證 0 leq n leq 10 拿到乙個1e18的題,第一反應肯定是先打個表看看嘛。我們知道有楊輝三角 1 1 1 1 2 1 1 ...
bzoj4403 序列統計 Lucas,組合數學
求有多少個長度為n nn的單調不公升序列,且對於每個元素都 l r in l,r l,r 我們讓m r l 1 m r l 1 m r l 1,因為序列的要求起始起始不會影響結果 然後我們開始考慮,我們在長度為n nn的序列全中1序列中我們可以每次選擇乙個位置讓後面的數都加1,然後選擇的個數不能超過...