Skip to content

Commit

Permalink
add: contest weekly 375
Browse files Browse the repository at this point in the history
  • Loading branch information
binacs committed Dec 16, 2023
1 parent 8f24ca8 commit 257869c
Showing 1 changed file with 120 additions and 0 deletions.
120 changes: 120 additions & 0 deletions math/combinatorics/combination.md
Original file line number Diff line number Diff line change
Expand Up @@ -1879,6 +1879,126 @@ public:

* * *

> [!NOTE] **[LeetCode 2963. 统计好分割方案的数目](https://leetcode.cn/problems/count-the-number-of-good-partitions/)**
>
> 题意: TODO
> [!TIP] **思路**
>
> 区间合并 + 组合数 (后者也可转化成 $2^{m-1}$ 思考)
<details>
<summary>详细代码</summary>
<!-- tabs:start -->

##### **C++**

```cpp
using LL = long long;
const static int N = 1e5 + 10, MOD = 1e9 + 7;

int qmi(int a, int k, int p) {
int ret = 1;
while (k) {
if (k & 1)
ret = (LL)ret * a % p;
a = (LL)a * a % p;
k >>= 1;
}
return ret;
}

int fact[N], infact[N];
bool inited = false;

void init() {
if (inited)
return;
inited = true;

fact[0] = infact[0] = 1;
for (int i = 1; i < N; ++ i ) {
fact[i] = (LL)fact[i - 1] * i % MOD;
infact[i] = (LL)infact[i - 1] * qmi(i, MOD - 2, MOD) % MOD;
}
}

int comb(int a, int b) {
return (LL)fact[a] * infact[b] % MOD * infact[a - b] % MOD;
}

class Solution {
public:
using PII = pair<int, int>;

void merge(vector<PII> & segs) {
vector<PII> res;
sort(segs.begin(), segs.end());
int st = -2e9, ed = -2e9;
for (auto seg : segs)
if (ed < seg.first) {
if (st != -2e9)
res.push_back({st, ed});
st = seg.first, ed = seg.second;
} else
ed = max(ed, seg.second);
if (st != -2e9)
res.push_back({st, ed});
segs = res;
}

int numberOfGoodPartitions(vector<int>& nums) {
init();

int n = nums.size();

unordered_set<int> S;
unordered_map<int, int> l, r;
{
// 先找到 最左侧/最右侧 出现的位置
for (int i = 0; i < n; ++ i ) {
int x = nums[i];
if (S.count(x)) {
l[x] = min(l[x], i), r[x] = max(r[x], i);
} else {
l[x] = r[x] = i;
S.insert(x);
}
}
}
vector<PII> xs;
{
// 根据出现过的元素划分基本区间
for (auto [k, v] : l)
xs.push_back({v, r[k]});
// 区间合并
merge(xs);
}

// 留下的都是可以任意合并的区间
// 最坏情况下 m=1e5
int m = xs.size(), res = 0;
for (int i = 0; i < m; ++ i )
// C{m-1}{i}
res = (res + comb(m - 1, i)) % MOD;
return res;
}
};
```
##### **Python**
```python
```

<!-- tabs:end -->
</details>

<br>

* * *

### 排列数

> [!NOTE] **[AcWing 1309. 车的放置](https://www.acwing.com/problem/content/1311/)** [TAG]
Expand Down

0 comments on commit 257869c

Please sign in to comment.