Skip to content

Commit

Permalink
add: weekly 399,400
Browse files Browse the repository at this point in the history
  • Loading branch information
binacs committed Aug 12, 2024
1 parent 2ffc95f commit 4abe192
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 26 deletions.
119 changes: 119 additions & 0 deletions ds/seg.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
> [!NOTE] **敏感度**
>
> 如果一个题目可以用分治解决,那么这个题目的带修改版本可以用线段树解决

线段树是算法竞赛中常用的用来维护 **区间信息** 的数据结构。

Expand Down Expand Up @@ -3327,6 +3331,121 @@ public:

* * *

> [!NOTE] **[LeetCode 3165. 不包含相邻元素的子序列的最大和](https://leetcode.cn/problems/maximum-sum-of-subsequence-with-non-adjacent-elements/)** [TAG]
>
> 题意: TODO

> [!TIP] **思路**
>
> 如果一个题目可以用分治解决,那么这个题目的带修改版本可以用线段树解决
>
> 线段树维护区间性质

<details>
<summary>详细代码</summary>
<!-- tabs:start -->

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

```cpp
class Solution {
public:
// 题意说明: 选择的子数组可以为空 则本质上是要求尽可能多的不连续的正数的和
// 带修改维护会比较麻烦 考虑线段树
//
// 考虑合并的影响 每一段按照是否包含 首/尾 两个字符做分类 00二进制
// f00[u] = max(f01[p] + f00[q], f00[p] + f10[q])
// f01[u] = max(f00[p] + f01[q], f00[p] + f11[q], f01[p] + f01[q])
// f10[u] = max(f10[p] + f00[q], f10[p] + f10[q], f11[p] + f00[q])
// f11[u] = max(f10[p] + f11[q], f11[p] + f01[q])

using LL = long long;
const static int N = 5e4 + 10, MOD = 1e9 + 7;

struct Node {
int l, r;
LL nlr, nl, nr, lr; // 没有左右 没左 没右 都有
} tr[N << 2];
void pushup(Node & u, Node & l, Node & r) {
u.nlr = u.nl = u.nr = u.lr = 0;
u.nlr = max({0ll, l.nl + r.nlr, l.nlr + r.nr});
u.nl = max({0ll, l.nlr + r.nl, l.nlr + r.lr, l.nl + r.nl});
u.nr = max({0ll, l.nr + r.nlr, l.nr + r.nr, l.lr + r.nlr});
u.lr = max({0ll, l.nr + r.lr, l.lr + r.nl});
}
void pushup(int u) {
pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}

vector<int> w;

void build(int u, int l, int r) {
if (l == r)
tr[u] = {l, r, 0, 0, 0, w[l]}; // ATTENTION
else {
tr[u] = {l, r};
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
}
void modify(int u, int x, int y) {
if (tr[u].l == x && tr[u].r == x)
tr[u] = {x, x, 0, 0, 0, y};
else {
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid)
modify(u << 1, x, y);
else
modify(u << 1 | 1, x, y);
pushup(u);
}
}
Node query(int u, int l, int r) {
if (tr[u].l >= l && tr[u].r <= r)
return tr[u];
else {
int mid = tr[u].l + tr[u].r >> 1;
if (r <= mid)
return query(u << 1, l, r);
else if (l > mid)
return query(u << 1 | 1, l, r);
Node ret;
auto left = query(u << 1, l, r);
auto right = query(u << 1 | 1, l, r);
pushup(ret, left, right);
return ret;
}
}

int maximumSumSubsequence(vector<int>& nums, vector<vector<int>>& queries) {
this->w = nums;
int n = w.size();
build(1, 0, n - 1);

LL res = 0;
for (auto & q : queries) {
modify(1, q[0], q[1]);
res = (res + max(0ll, query(1, 0, n - 1).lr)) % MOD;
}
return res;
}
};
```
##### **Python**
```python
```

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

<br>

* * *

### 二进制拆位线段树

> [!NOTE] **[Codeforces XOR on Segment](http://codeforces.com/problemset/problem/242/E)**
Expand Down
123 changes: 97 additions & 26 deletions topic/bf-improve.md
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ int main() {
<summary>详细代码</summary>
<!-- tabs:start -->

##### **C++ 直接统计**
##### **C++ 标准**

```cpp
class Solution {
Expand All @@ -587,7 +587,7 @@ public:
for (int i = 0; i < n; ++ i ) {
S.insert(arr[i]);
for (int j = i - 1; j >= 0; -- j ) {
// ATTENTION
// ATTENTION 注意括号 (x | y) == z
if ((arr[j] | arr[i]) == arr[j])
break;
arr[j] |= arr[i];
Expand Down Expand Up @@ -1131,6 +1131,55 @@ public:

* * *

> [!NOTE] **[LeetCode 3171. 找到按位或最接近 K 的子数组](https://leetcode.cn/problems/find-subarray-with-bitwise-or-closest-to-k/)**
>
> 题意: TODO
> [!TIP] **思路**
>
> 经典 LogTrick
>
> 子数组按位 ``
<details>
<summary>详细代码</summary>
<!-- tabs:start -->

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

```cpp
class Solution {
public:
int minimumDifference(vector<int>& nums, int k) {
int res = 2e9;
int n = nums.size();
for (int i = 0; i < n; ++ i ) {
res = min(res, abs(nums[i] - k));
for (int j = i - 1; j >= 0; -- j ) {
if ((nums[j] | nums[i]) == nums[j])
break;
nums[j] |= nums[i];
res = min(res, abs(nums[j] - k));
}
}
return res;
}
};
```
##### **Python**
```python
```

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

<br>

* * *

> [!NOTE] **[LeetCode 1521. 找到最接近目标值的函数值](https://leetcode.cn/problems/find-a-value-of-a-mysterious-function-closest-to-target/)** [TAG]
>
> 题意: TODO
Expand All @@ -1149,6 +1198,52 @@ public:
<summary>详细代码</summary>
<!-- tabs:start -->

##### **C++ 标准**

```cpp
class Solution {
public:
int closestToTarget(vector<int>& arr, int target) {
int res = 1e9;
int n = arr.size();
for (int i = 0; i < arr.size(); ++ i ) {
res = min(res, abs(arr[i] - target));
for (int j = i - 1; j >= 0; -- j ) {
if ((arr[j] & arr[i]) == arr[j])
break;
arr[j] &= arr[i];
res = min(res, abs(arr[j] - target));
}
}
return res;
}
};
```
##### **C++ 动态维护 非原地修改**
```cpp
class Solution {
public:
int closestToTarget(vector<int>& arr, int target) {
int ans = abs(arr[0] - target);
vector<int> valid = {arr[0]};
for (int num : arr) {
vector<int> validNew = {num};
ans = min(ans, abs(num - target));
for (int prev : valid) {
validNew.push_back(prev & num);
ans = min(ans, abs((prev & num) - target));
}
validNew.erase(unique(validNew.begin(), validNew.end()),
validNew.end());
valid = validNew;
}
return ans;
}
};
```

##### **C++ 双指针+前缀和**

```cpp
Expand Down Expand Up @@ -1191,30 +1286,6 @@ public:
};
```
##### **C++ 动态维护**
```cpp
class Solution {
public:
int closestToTarget(vector<int>& arr, int target) {
int ans = abs(arr[0] - target);
vector<int> valid = {arr[0]};
for (int num : arr) {
vector<int> validNew = {num};
ans = min(ans, abs(num - target));
for (int prev : valid) {
validNew.push_back(prev & num);
ans = min(ans, abs((prev & num) - target));
}
validNew.erase(unique(validNew.begin(), validNew.end()),
validNew.end());
valid = validNew;
}
return ans;
}
};
```

##### **C++ 模拟退火**
```cpp
Expand Down

0 comments on commit 4abe192

Please sign in to comment.