【CF】Day82——Codeforces Round 869 (Div. 2) CD (前缀和 | ⭐无向图找环)
C. Almost Increasing Subsequence
题目:
思路:
前缀和立大功
一个很显然的想法,我们可以拆开整个序列来看看,我们将序列分为 递减子序列 和 剩余情况,那么对于一个递减子序列,其前后要么就是其余情况,要么就是没有元素
那么贪心的想,对于一个递减子序列,我们能选多少个元素呢?显然最多选两个,所以我们可以考虑前缀和来做
我们定义 sum[i] 为前 i 个元素中有多少个元素是 x >= y >= z 的
那么答案就是 len - (sum[r] - sum[l+1])
为什么是这个呢?由于 sum[i] 和 a[i-1] a[i-2] 有关,但是对于现在来说我们最多只能选 a[i],不能往前选,那么为了限制区间,我们就要选 sum[i+2] 这样就和 a[i+1] a[i] 有关了,但是还要记得我们要减去的应该是 i+2 前面的 (因为要包括 i),所以要减去 sum[l + 1] 而不是 sum[l + 2] (类比正常前缀和)
代码:
#include <iostream>
#include <algorithm>
#include<cstring>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <memory>
using namespace std;
#define int long long
#define yes cout << "Yes\n"
#define no cout << "No\n"void solve()
{int n, q;cin >> n >> q;vector<int> a(n+1,0);for (int i = 1; i <= n; i++){cin >> a[i];}vector<int> sum(n + 2, 0);for (int i = 3; i <= n; i++){sum[i] = sum[i - 1];if (a[i-2] >= a[i-1] && a[i-1] >= a[i]){sum[i]++;}}for (int i = 0; i < q; i++){int l, r;cin >> l >> r;int len = r - l + 1;if (len < 3){cout << len << endl;continue;}cout << len - (sum[r] - sum[l + 1]) << endl;}
}signed main()
{cin.tie(0)->sync_with_stdio(false);int t = 1;while (t--){solve();}return 0;
}
D. Fish Graph
题目:

思路:
无向图找环,得开一篇学学
很简单的一题,只要你会找环
题目化简一下就是找到一个环,且满足这个环上至少有一点连接了2个除环上点以外的点
由于 n 和 m 都很小,那么直接暴力找即可
具体的我们可以枚举那个特殊点,这个特殊点满足度大于等于 4,然后模拟即可
代码:
#include <iostream>
#include <algorithm>
#include<cstring>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <memory>
using namespace std;
#define int long long
#define yes cout << "Yes\n"
#define no cout << "No\n"void solve()
{int n, m;cin >> n >> m;vector<vector<int>> g(n + 1);for (int i = 0; i < m; i++){int u, v;cin >> u >> v;g[u].push_back(v);g[v].push_back(u);}int flag = 0;vector<int> vis(n + 1, 0),col(n+1,0),p;auto dfs = [&](auto self, int fa, int se, int root) -> void {if (flag) return;vis[se] = 1;p.push_back(se);for (auto& son : g[se]){if (flag)return;if (fa == son) continue;if (son == root && fa != root){for (int i = 1; i <= n; i++){col[i] = 0;}for (auto & pi : p){col[pi] = 1;}int excnt = 0;for (auto& next : g[root]){if (col[next] != 1)excnt++;if (excnt >= 2)break;}if (excnt < 2){continue;}yes;cout << p.size() + 2 << endl;for (int i = p.size() - 1; i >= 1; i--){cout << p[i] << " " << p[i - 1] << endl;}cout << root << " " << se << endl;excnt = 0;for (auto& next : g[root]){if (col[next] != 1)excnt++, cout << root << " " << next << endl;if (excnt >= 2)break;}flag = 1;return;}if(vis[son] != 1)self(self, se, son, root);}p.pop_back();};for (int i = 1; !flag && i <= n; i++){if (g[i].size() < 4){continue;} for (int j = 1; j <= n; j++){vis[j] = 0;}p.clear();dfs(dfs, 0, i, i);}if (!flag)no;
}signed main()
{cin.tie(0)->sync_with_stdio(false);int t = 1;cin >> t;while (t--){solve();}return 0;
}