This commit is contained in:
Zengtudor 2024-08-04 09:06:39 +08:00
parent c3817c55d8
commit f5219579b9
16 changed files with 391 additions and 0 deletions

13
day3/T490194/T490194.cpp Normal file
View File

@ -0,0 +1,13 @@
#include<bits/stdc++.h>
using namespace std;
int n,m;
int main(){
cin.sync_with_stdio(false);
cin.tie(0);
vector<int> v(n);
}

BIN
day3/T490194/chat Executable file

Binary file not shown.

70
day3/T490194/chat.cpp Normal file
View File

@ -0,0 +1,70 @@
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
struct Info {
int l, r, val;
};
int main() {
int n, m;
cin >> n >> m;
vector<Info> infos(m);
for (int i = 0; i < m; ++i) {
cin >> infos[i].l >> infos[i].r >> infos[i].val;
}
vector<int> p(n + 1, -1);
vector<set<int>> mex_sets(n + 1);
for (int i = 0; i <= n; ++i) {
mex_sets[i].insert(0);
}
for (const auto& info : infos) {
for (int i = info.l; i <= info.r; ++i) {
if (info.val > 0) {
mex_sets[i].erase(info.val - 1);
}
mex_sets[i].insert(info.val);
}
}
for (int i = 0; i <= n; ++i) {
if (p[i] == -1) {
auto it = mex_sets[i].begin();
p[i] = *it;
}
}
bool valid = true;
for (const auto& info : infos) {
set<int> s;
for (int i = info.l; i <= info.r; ++i) {
s.insert(p[i]);
}
int expected_mex = 0;
while (s.count(expected_mex)) {
++expected_mex;
}
if (expected_mex != info.val) {
valid = false;
break;
}
}
if (valid) {
for (int i = 0; i <= n; ++i) {
cout << p[i] << " ";
}
cout << endl;
} else {
cout << "-1" << endl;
}
return 0;
}

118
day3/T490194/chat.md Normal file
View File

@ -0,0 +1,118 @@
这个问题要求我们根据给定的若干条信息,重建一个 $0 \sim n$ 的排列 $p$。这些信息描述了某些区间的 ${\rm mex}$ 值。${\rm mex}$ 是指最小的没有在该区间内出现的非负整数。
我们需要根据这些条件构造一个满足所有信息的排列,或者判断是否无解。
## 问题分析和思路
1. **理解 ${\rm mex}$ 的定义**:
${\rm mex}$ (minimum excluded value) 是一个区间中未出现的最小非负整数。例如,在区间 `[0, 2, 3]` 中,${\rm mex}$ 是 `1`,因为 `1` 是未出现的最小非负整数。
2. **信息的限制**:
给定若干条信息,每条信息形如 `(l, r, val)`,表示区间 `[l, r]` 的 ${\rm mex}$ 值为 `val`
3. **构造思路**:
- 初始化一个大小为 `n+1` 的数组 `p`,所有元素初始化为 `-1`,表示未被确定的值。
- 遍历给定的所有区间信息,逐步填充数组 `p`
- 检查每个区间的 ${\rm mex}$ 信息,确保填充的值符合所有给定的条件。
4. **区间处理**:
- 我们需要确保在给定区间 `[l, r]` 中,`val` 是该区间中未出现的最小非负整数。
- 使用区间处理算法(如线段树或差分数组)来高效地处理和验证区间信息。
## 详细算法步骤
1. **初始化**:
- 创建数组 `p`,大小为 `n+1`,所有元素初始化为 `-1`
- 创建一个辅助数组 `fixed`,大小为 `n+1`,用于标记哪些位置已经被确定。
2. **处理区间信息**:
- 对于每条信息 `(l, r, val)`:
- 确保区间 `[l, r]` 中没有比 `val` 更小的未出现的非负整数。
- 如果在处理过程中发现矛盾(如 `val` 已经在区间内出现但仍被认为是未出现的最小非负整数),则判定无解。
3. **验证和填充**:
- 遍历数组 `p`,确保所有位置都被有效填充。
- 如果有未填充的位置,则根据已知信息进行推断和填充。
4. **输出结果**:
- 如果构造成功,输出数组 `p`
- 如果无法构造,输出 `-1`
## C++ 实现
```cpp
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
struct Info {
int l, r, val;
};
int main() {
int n, m;
cin >> n >> m;
vector<Info> infos(m);
for (int i = 0; i < m; ++i) {
cin >> infos[i].l >> infos[i].r >> infos[i].val;
}
vector<int> p(n + 1, -1);
vector<set<int>> mex_sets(n + 1);
for (int i = 0; i <= n; ++i) {
mex_sets[i].insert(0);
}
for (const auto& info : infos) {
for (int i = info.l; i <= info.r; ++i) {
if (info.val > 0) {
mex_sets[i].erase(info.val - 1);
}
mex_sets[i].insert(info.val);
}
}
for (int i = 0; i <= n; ++i) {
if (p[i] == -1) {
auto it = mex_sets[i].begin();
p[i] = *it;
}
}
bool valid = true;
for (const auto& info : infos) {
set<int> s;
for (int i = info.l; i <= info.r; ++i) {
s.insert(p[i]);
}
int expected_mex = 0;
while (s.count(expected_mex)) {
++expected_mex;
}
if (expected_mex != info.val) {
valid = false;
break;
}
}
if (valid) {
for (int i = 0; i <= n; ++i) {
cout << p[i] << " ";
}
cout << endl;
} else {
cout << "-1" << endl;
}
return 0;
}
```
这个实现利用了 `set` 结构来动态维护每个位置的可能 `mex` 值,并在最后一步进行验证。如果验证通过,则输出构造的排列;如果不通过,则输出 `-1` 表示无解。
此实现的时间复杂度大约是 $O(nm)$,因为需要遍历每个区间的信息,并对每个位置的 `mex` 进行维护。对于较大的输入数据,可能需要进一步优化。

BIN
day3/U184510/chat Executable file

Binary file not shown.

34
day3/U184510/chat.cpp Normal file
View File

@ -0,0 +1,34 @@
#include <iostream>
#include <vector>
using namespace std;
const int MOD = 1e9 + 7;
int mod_inv(int a, int m) {
int m0 = m, t, q;
int x0 = 0, x1 = 1;
if (m == 1) return 0;
while (a > 1) {
q = a / m;
t = m;
m = a % m, a = t;
t = x0;
x0 = x1 - q * x0;
x1 = t;
}
if (x1 < 0) x1 += m0;
return x1;
}
int main() {
int n;
cin >> n;
vector<long long> dp(n + 1, 0);
for (int i = 2; i <= n; ++i) {
dp[i] = (dp[i - 1] + (i * (i - 1) / 2) % MOD * mod_inv(i, MOD)) % MOD;
}
cout << dp[n] << endl;
return 0;
}

9
day3/U86432/U86432.cpp Normal file
View File

@ -0,0 +1,9 @@
#include<bits/stdc++.h>
using namespace std;
int n,m,r,k;
int main(){
cin>>n>>m>>r>>k;
}

BIN
day3/U86432/chat Executable file

Binary file not shown.

47
day3/U86432/chat.cpp Normal file
View File

@ -0,0 +1,47 @@
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, m, r, k;
cin >> n >> m >> r >> k;
vector<vector<int>> fish_count(n + 1, vector<int>(m + 1, 0));
for (int i = 0; i < k; ++i) {
int x, y;
cin >> x >> y;
fish_count[x][y]++;
}
vector<vector<int>> prefix(n + 1, vector<int>(m + 1, 0));
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
prefix[i][j] = fish_count[i][j]
+ (i > 1 ? prefix[i - 1][j] : 0)
+ (j > 1 ? prefix[i][j - 1] : 0)
- (i > 1 && j > 1 ? prefix[i - 1][j - 1] : 0);
}
}
unordered_map<int, long long> result;
for (int i = 1; i <= n - r + 1; ++i) {
for (int j = 1; j <= m - r + 1; ++j) {
int x1 = i, y1 = j;
int x2 = i + r - 1, y2 = j + r - 1;
int fish_in_net = prefix[x2][y2]
- (x1 > 1 ? prefix[x1 - 1][y2] : 0)
- (y1 > 1 ? prefix[x2][y1 - 1] : 0)
+ (x1 > 1 && y1 > 1 ? prefix[x1 - 1][y1 - 1] : 0);
result[fish_in_net]++;
}
}
// Output results
for (int i = 0; i <= k; ++i) {
cout << result[i] << endl;
}
return 0;
}

BIN
day3/review/main Executable file

Binary file not shown.

BIN
day3/review/冒泡排序 Executable file

Binary file not shown.

View File

@ -0,0 +1,31 @@
#include <bits/stdc++.h>
using namespace std;
#define PRINT_VEC(v){\
cout<<#v<<" [";\
for(size_t i=0;i<v.size();i++){\
cout<<v[i]<<(i!=v.size()-1?",":"]\n");\
}\
}
void sort_fix(vector<int> &v){
for(size_t i=0;i<v.size()-1;i++){
for(size_t j=i;j<v.size()-i-1;j++){
if (v[j]>v[j+1]) {
swap(v[j],v[j+1]);
}
}
}
}
int main(){
size_t n;
cin>>n;
vector<int> v(n);
for(int &i:v){
cin>>i;
}
PRINT_VEC(v);
sort_fix(v);
PRINT_VEC(v);
}

BIN
day3/review/插入排序 Executable file

Binary file not shown.

View File

@ -0,0 +1,33 @@
#include<bits/stdc++.h>
using namespace std;
#define PRINT_VEC(v){\
cout<<#v<<" [";\
for(size_t i=0;i<v.size();i++){\
cout<<v[i]<<(i!=v.size()-1?",":"]\n");\
}\
}
void sort_fix(vector<int> &v){
for(size_t i=1;i<v.size();i++){
int key=v[i];
int j=i-1;
while(j>=0&&v[j]>key){
v[j+1]=v[j];
--j;
}
v[j+1]=key;
}
}
int main(){
size_t n;
cin>>n;
vector<int> v(n);
for(int &i:v){
cin>>i;
}
PRINT_VEC(v);
sort_fix(v);
PRINT_VEC(v);
}

BIN
day3/review/选择排序 Executable file

Binary file not shown.

View File

@ -0,0 +1,36 @@
#include<bits/stdc++.h>
using namespace std;
#define PRINT_VEC(v){\
cout<<#v<<" [";\
for(size_t i=0;i<v.size();i++){\
cout<<v[i]<<(i!=v.size()-1?",":"]\n");\
}\
}
void sort_fix(vector<int> &v){
for(size_t i=0;i<v.size();i++){
int min_num=INT_MAX;
size_t min_dir=0;
for(size_t j=i;j<v.size();j++){
if(min_num>v[j]){
min_num=v[j];
min_dir=j;
}
}
swap(v[i],v[min_dir]);
}
}
int main(){
size_t n;
cin>>n;
vector<int> v(n);
for(int &i:v){
cin>>i;
}
PRINT_VEC(v);
sort_fix(v);
PRINT_VEC(v);
}