-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
adj-diff-tree use monoid; add slide-window;
- Loading branch information
old-yan
committed
Oct 13, 2024
1 parent
be36edc
commit 5764cab
Showing
16 changed files
with
385 additions
and
147 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
最后修改: | ||
20241013 | ||
测试环境: | ||
gcc11.2,c++14 | ||
clang12.0,C++14 | ||
msvc14.2,C++14 | ||
*/ | ||
#ifndef __OY_SLIDEWINDOW__ | ||
#define __OY_SLIDEWINDOW__ | ||
|
||
#include <algorithm> | ||
#include <cstdint> | ||
#include <numeric> | ||
#include <vector> | ||
|
||
namespace OY { | ||
namespace WINDOW { | ||
using size_type = uint32_t; | ||
template <typename Callback, typename ShortenLeft, typename LengthenRight> | ||
void solve(size_type length, size_type window_len, Callback &&call, ShortenLeft &&left_call, LengthenRight &&right_call) { | ||
size_type l = 0, r = 0; | ||
while (r != window_len) right_call(r++); | ||
call(l, r - 1); | ||
while (r != length) { | ||
left_call(l++); | ||
right_call(r++); | ||
call(l, r - 1); | ||
} | ||
} | ||
} | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
### 一、模板类别 | ||
|
||
数据结构:滑动窗口。 | ||
|
||
练习题目: | ||
|
||
1. [3321. 计算子数组的 x-sum II](https://leetcode.cn/problems/find-x-sum-of-all-k-long-subarrays-ii) | ||
|
||
|
||
### 二、模板功能 | ||
|
||
本模板提供一个滑动窗口模板。 | ||
|
||
滑动窗口问题中,需要知道区间总长度、窗口长度、窗口左端收缩的回调函数、窗口右端收缩的回调函数、窗口就绪的回调函数。只要传递这些参数,本模板即可自动运行。 | ||
|
||
### 三、模板示例 | ||
|
||
```c++ | ||
#include "IO/FastIO.h" | ||
#include "MISC/SlideWindow.h" | ||
|
||
#include <map> | ||
void test() { | ||
// 窗口数颜色 | ||
cout << "count color count:\n"; | ||
int a[] = {4, 7, 5, 1, 8, 1, 4, 4, 1}; | ||
|
||
int n = 9; | ||
int window_len = 4; | ||
std::map<int, int> mp; | ||
auto call = [&](int l, int r) { | ||
cout << "color count of ["; | ||
for (int i = l; i <= r; i++) cout << a[i] << " ]"[i == r]; | ||
cout << " = " << mp.size() << endl; | ||
}; | ||
auto left_call = [&](int i) { | ||
auto &cnt = mp[a[i]]; | ||
if (!--cnt) mp.erase(a[i]); | ||
}; | ||
auto right_call = [&](int i) { | ||
auto &cnt = mp[a[i]]; | ||
++cnt; | ||
}; | ||
OY::WINDOW::solve(n, window_len, call, left_call, right_call); | ||
} | ||
|
||
int main() { | ||
test(); | ||
} | ||
``` | ||
|
||
``` | ||
#输出如下 | ||
count color count: | ||
color count of [4 7 5 1] = 4 | ||
color count of [7 5 1 8] = 4 | ||
color count of [5 1 8 1] = 3 | ||
color count of [1 8 1 4] = 3 | ||
color count of [8 1 4 4] = 3 | ||
color count of [1 4 4 1] = 2 | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#include "IO/FastIO.h" | ||
#include "MISC/SlideWindow.h" | ||
|
||
#include <map> | ||
void test() { | ||
// 窗口数颜色 | ||
cout << "count color count:\n"; | ||
int a[] = {4, 7, 5, 1, 8, 1, 4, 4, 1}; | ||
|
||
int n = 9; | ||
int window_len = 4; | ||
std::map<int, int> mp; | ||
auto call = [&](int l, int r) { | ||
cout << "color count of ["; | ||
for (int i = l; i <= r; i++) cout << a[i] << " ]"[i == r]; | ||
cout << " = " << mp.size() << endl; | ||
}; | ||
auto left_call = [&](int i) { | ||
auto &cnt = mp[a[i]]; | ||
if (!--cnt) mp.erase(a[i]); | ||
}; | ||
auto right_call = [&](int i) { | ||
auto &cnt = mp[a[i]]; | ||
++cnt; | ||
}; | ||
OY::WINDOW::solve(n, window_len, call, left_call, right_call); | ||
} | ||
|
||
int main() { | ||
test(); | ||
} | ||
/* | ||
#输出如下 | ||
count color count: | ||
color count of [4 7 5 1] = 4 | ||
color count of [7 5 1 8] = 4 | ||
color count of [5 1 8 1] = 3 | ||
color count of [1 8 1 4] = 3 | ||
color count of [8 1 4 4] = 3 | ||
color count of [1 4 4 1] = 2 | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#include "DS/MonoAVL.h" | ||
#include "DS/MonoSplay.h" | ||
#include "IO/LeetcodeIO.h" | ||
#include "MISC/SlideWindow.h" | ||
using namespace std; | ||
|
||
/* | ||
[3321. 计算子数组的 x-sum II](https://leetcode.cn/problems/find-x-sum-of-all-k-long-subarrays-ii) | ||
*/ | ||
/** | ||
* 滑动窗口模板,平衡树模板 | ||
*/ | ||
|
||
class Solution { | ||
public: | ||
vector<long long> findXSum(vector<int> &nums, int k, int x) { | ||
// 本平衡树维护两个属性的和 | ||
// 属性一是频率 | ||
// 属性二是键和频率的乘积 | ||
struct Monoid { | ||
using value_type = pair<int, long long>; | ||
static value_type op(value_type x, value_type y) { return {x.first + y.first, x.second + y.second}; } | ||
static value_type identity() { return {0, 0}; } | ||
}; | ||
using Tree = OY::MONOAVL::Tree<Monoid, false>; | ||
// using Tree = OY::MONOSPLAY::Tree<Monoid, false>; | ||
Tree S; | ||
// mp 维护频率 | ||
unordered_map<int, int> mp; | ||
vector<long long> ans; | ||
// 给固定大小的滑动窗口传递回调函数 | ||
// 对已就绪的窗口调用的回调 | ||
auto call = [&](int l, int r) { | ||
if (S.size() < x) | ||
ans.push_back(S.query_all().second); | ||
else | ||
ans.push_back(S.query(S.size() - x, S.size() - 1).second); | ||
}; | ||
// 左端点右移的回调 | ||
auto left_call = [&](int i) { | ||
auto &cnt = mp[nums[i]]; | ||
if (cnt) S.erase_by_comparator({cnt, 1ll * nums[i] * cnt}); | ||
--cnt; | ||
if (cnt) S.insert_by_comparator({cnt, 1ll * nums[i] * cnt}); | ||
}; | ||
// 右端点右移的回调 | ||
auto right_call = [&](int i) { | ||
auto &cnt = mp[nums[i]]; | ||
if (cnt) S.erase_by_comparator({cnt, 1ll * nums[i] * cnt}); | ||
++cnt; | ||
if (cnt) S.insert_by_comparator({cnt, 1ll * nums[i] * cnt}); | ||
}; | ||
OY::WINDOW::solve(nums.size(), k, call, left_call, right_call); | ||
return ans; | ||
} | ||
}; | ||
|
||
#ifdef OY_LOCAL | ||
int main() { | ||
REGISTER_CONSTRUCTOR_SOLUTION; | ||
REGISTER_MEMBERFUNCTION_SOLUTION(findXSum); | ||
while (true) { | ||
executor.constructSolution(); | ||
executor.executeSolution(); | ||
} | ||
} | ||
#endif |
Oops, something went wrong.