【CF】Day77——Codeforces Round 877 (Div. 2) BCD (构造场)
B. Minimize Permutation Subarrays
题目:

思路:
考虑了一半,小失误
首先我们考虑答案至少有几个,显然至少有两个,一个是 1,一个是 1 ~ n,即只选 1 和 全选
那么再考虑是否能让答案只有这两个呢?
显然是可以的,我们只需要将 n 放在 1 和 2 的中间即可,即 1 n 2 或 2 n 1 的形式,因为如果要有 2,那么必须就要经过 n,那么此时如果不全选是无法构造出一个排列的,所以这个方法可行,同时也只需要一步
代码:
#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;cin >> n;vector<int> a(n+1);vector<int> idx(n + 1);for (int i = 1; i <= n; i++){cin >> a[i];idx[a[i]] = i;}if (idx[n] < min(idx[1], idx[2])) {cout << idx[n] << ' ' << min(idx[1], idx[2]) << '\n';}else if (idx[n] > max(idx[1], idx[2])) {cout << idx[n] << ' ' << max(idx[1], idx[2]) << '\n';}else {cout << idx[1] << ' ' << idx[2] << '\n';}
}signed main()
{cin.tie(0)->sync_with_stdio(false);int t = 1;cin >> t;while (t--){solve();}return 0;
}
C. No Prime Differences
题目:

思路:
对脑电波
首先我们得想到1是一个非质数,那么我们可以构造形如 1 2 3 4 5..这样的连续数列当作一行
那么任意两行间的差就是 m 了,这显然是不行的,如果 m 是质数就炸了,所以考虑优化
既然不能是 m,那我 2*m 不久行了吗?
所以我们可以这样构造,对于 n = 5,m = 5 的情况,我们只需要
11 12 13 14 15
1 2 3 4 5
16 17 18 19 20
6 7 8 9 10
21 22 23 24 25
即偶数个 m 和奇数个 m交替放,同时每放一次就将偶数奇数加 1
代码:
#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;int ji = 0, ou = n / 2;for (int i = 1; i <= n; i++){if (i % 2 ==0){for (int j = 1; j <= m; j++){cout << ji *m + j << " ";}ji++;cout << endl;}else{for (int j = 1; j <= m; j++){cout << ou * m + j << " ";}ou++;cout << endl;}}
}signed main()
{cin.tie(0)->sync_with_stdio(false);int t = 1;cin >> t;while (t--){solve();}return 0;
}
D. Bracket Walk
题目:

思路:
想到了,但不会证明(果然ACM不需要证明)
显然,对于 (),)( 的结构我们反复走是无所谓的,唯独 (( 和 )) 是反复走有用的,因为我们可以不断重复走然后构造出无数个 ( 或 )
那么看看什么时候无法构造,首先 n 是奇数时是不可能的,因为你无论怎么走最后一定是 n + 2*k 个括号,n 是奇数,2*k是偶数,所以最后一定是奇数个括号,那么一定无法构造
那么偶数呢?首先如果首是 ) 或者尾是 ( 肯定是不行的,那其余情况呢?
上面我们说 (( 和 )) 是有影响的,所以我们可以记录 (( 和 )) 的位置
如果 有 (( 但是 没 )),说明是类似 ()()()(()... 的机构,此时一定无法消除多余的 (,那么就不行,同理如果只有 )) 没 (( 也是一样的
如果都没那就是 ()()()()()()(),此时就是直接走即可,那么如果都有呢?
如果都有的话,只要有 )) 出现在第一个 (( 之前就不行,因为此时无法消除 ),除此之外一定可以,因为我们可以不断走 (( 来修正多的 ) ,所以一定可以
代码:
#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;string s;cin >> s;s = '&' + s;set<int> L, R;for (int i = 1; i < n; i++){if (s[i] == s[i + 1]){if (s[i] == '(')L.insert(i);elseR.insert(i);}}auto check = [&]() ->int{if (n % 2 || s[1] == ')' || s[n] == '(')return 0;else if (L.empty() && R.empty()) return 1;else if (L.empty() || R.empty())return 0;else if ((*L.begin() < *R.begin()) && (*L.rbegin() < *R.rbegin())) return 1;else return 0;};for (int i = 0; i < q; i++){int x; cin >> x;if (x != 1 && s[x] == s[x - 1]){if (s[x] == '(')L.erase(x-1);else R.erase(x-1);}if (x != n && s[x] == s[x + 1]){if (s[x] == '(')L.erase(x);else R.erase(x);}s[x] = (s[x] == '(') ? ')': '(';if (x != 1 && s[x] == s[x - 1]){if (s[x] == '(')L.insert(x - 1);else R.insert(x - 1);}if (x != n && s[x] == s[x + 1]){if (s[x] == '(')L.insert(x);else R.insert(x);}check() ? yes : no;}
}signed main()
{cin.tie(0)->sync_with_stdio(false);int t = 1;while (t--){solve();}return 0;
}