Educational Codeforces Round 149 (Rated for Div. 2) 题解
https://codeforces.com/contest/1837
https://codeforces.com/contest/1837/problems
利益相关:上紫祭。
真的不要以为这道题放在 F 就不敢做。
ABC 题都过水,就不写了。
代码丢在这里:
A:https://codeforces.com/contest/1837/submission/207156920
B:https://codeforces.com/contest/1837/submission/207180946
C:https://codeforces.com/contest/1837/submission/207186832
D. Bracket Coloring
首先猜测一个结论:
然后可以写一个程序验证:比如说对于每一个长度为 (
数量和 )
数量均为
接下来讲如何构造方案(其实构造方案就可以证明结论):
如果左括号数量不等于右括号数量,就直接暴毙,输出
否则如果
否则
构造策略:
枚举每一个左括号(下标为
剩下的染为颜色
Proof. 如果没有 ()
的子序列了,那肯定都是 )(
,一 reverse 就是 ()
,所以染两种颜色即可。
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
#define rep(i, l, r) for(int i = l;i <= r; ++ i)
#define per(i, r, l) for(int i = r;i >= l; -- i)
//#define int long long
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
inline int read () {
int x = 0, f = 0;
char c = getchar ();
for ( ; c < '0' || c > '9' ; c = getchar ()) f |= (c == '-');
for ( ; c >= '0' && c <= '9' ; c = getchar ()) x = (x << 1) + (x << 3) + (c & 15);
return !f ? x : -x;
}
int n, ans[200005];
char s[200005];
inline bool pd (string s) {
int cnt = 0;
int L = s.size ();
rep (i, 0, L - 1) {
if (s[i] == '(') cnt ++;
else {
if (cnt <= 0) return false;
cnt --;
}
}
if (cnt != 0) return false;
else return true;
}
inline bool judge (string S) {
string T = S;
reverse (T.begin (), T.end ());
return (pd (S) || pd (T));
}
signed main () {
int _ = read ();
while (_ --) {
n = read ();
scanf ("%s", s + 1);
int lf = 0, rt = 0;
rep (i, 1, n) {
lf += (s[i] == '(');
rt += (s[i] == ')');
}
string S = "";
rep (i, 1, n) S += s[i];
if (lf != rt) printf ("-1\n");
else if (judge (S)) {
printf ("1\n");
rep (i, 1, n) printf ("1 ");
printf ("\n");
}
else {
printf ("2\n");
vector < int > L, R;
L.clear (), R.clear ();
rep (i, 1, n) {
if (s[i] == '(') L.push_back (i);
else R.push_back (i);
}
rep (i, 1, n) ans[i] = 2;
int ls = L.size (), xb = R.size ();
-- xb;
rep (i, 0, ls - 1) {
if (L[i] <= R[xb]) ans[L[i]] = ans[R[xb]] = 1, xb --;
else break;
}
rep (i, 1, n) printf ("%d ", ans[i]);
printf ("\n");
}
}
return 0;
}
// Always keep it simple and stupid
F. Editorial for Two
容易发现,答案肯定是形如:
其中
同理,
Hint. 设
Proof. 随着
然后
但是代码有亿点点难写,尽量自己写。
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
#define rep(i, l, r) for(int i = l;i <= r; ++ i)
#define per(i, r, l) for(int i = r;i >= l; -- i)
#define int long long
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
inline int read () {
int x = 0, f = 0;
char c = getchar ();
for ( ; c < '0' || c > '9' ; c = getchar ()) f |= (c == '-');
for ( ; c >= '0' && c <= '9' ; c = getchar ()) x = (x << 1) + (x << 3) + (c & 15);
return !f ? x : -x;
}
const int N = 3e5 + 5, V = 1e7 + 10;
struct fhq_treap {
int root, tot;
struct node {int ls, rs, val, pri, siz;} tr[N];
inline void update (int u) {tr[u].siz = tr[tr[u].ls].siz + tr[tr[u].rs].siz + 1;}
inline void split (int u, int v, int &x, int &y) {
if (!u) {x = y = 0; return ;}
if (tr[u].val <= v) split (tr[u].rs, v, tr[x = u].rs, y);
else split (tr[u].ls, v, x, tr[y = u].ls);
update (u);
}
inline int merge (int x, int y) {
if (!x || !y) return x | y;
if (tr[x].pri < tr[y].pri) return tr[y].ls = merge (x, tr[y].ls), update (y), y;
return tr[x].rs = merge (tr[x].rs, y), update (x), x;
}
inline int create (int w) {int x = ++ tot; tr[x].val = w, tr[x].pri = randomly (1, V), tr[x].siz = 1; return x;}
inline void ins (int w) {
int x, y; x = y = 0;
split (root, w - 1, x, y);
root = merge (merge (x, create (w)), y);
}
inline void del (int w) {
int x, y, z; x = y = z = 0;
split (root, w, x, z), split (x, w - 1, x, y);
root = merge (merge (x, y = merge (tr[y].ls, tr[y].rs)), z);
}
inline int kth (int k) {
int u = root;
while (true) {
if (k <= tr[tr[u].ls].siz) u = tr[u].ls;
else if (k == tr[tr[u].ls].siz + 1) return tr[u].val;
else k -= tr[tr[u].ls].siz + 1, u = tr[u].rs;
}
}
inline int pre (int w) {
int u = root, ans = 0;
while (true) {
if (!u) return ans;
else if (w <= tr[u].val) u = tr[u].ls;
else ans = tr[u].val, u = tr[u].rs;
}
}
inline int nxt (int w) {
int u = root, ans = 0;
while (true) {
if (!u) return ans;
else if (w >= tr[u].val) u = tr[u].rs;
else ans = tr[u].val, u = tr[u].ls;
}
}
inline int rank (int w) {
int x, y, ans; x = y = ans = 0;
split (root, w - 1, x, y), ans = tr[x].siz + 1;
return root = merge (x, y), ans;
}
} pref, suff;
int n, k, a[300005], f;
int pre, suf, idx;
inline int mn () {
if (idx < f + 1 || n - idx < k - (f + 1)) return 1e18;
int P = pre, S = suf;
P += pref.kth (f + 1);
S -= suff.kth (k - f);
return max (P, S);
}
signed main () {
int _ = read ();
while (_ --) {
n = read (), k = read ();
rep (i, 1, n) a[i] = read ();
rep (i, 1, n) suff.ins (a[i]);
pre = suf = 0;
rep (i, 1, k) suf += suff.kth (i);
int ans = 1e18;
f = 0;
int sizp = 0, sizs = n;
rep (i, 0, n) {
idx = i;
if (i >= f && n - i >= k - f) ans = min (ans, max (pre, suf));
int cur = max (pre, suf);
if (i >= f && n - i >= k - f) ; else cur = 1e18;
while (f < k && cur >= mn () && mn () < 1e18) {
pre += pref.kth (f + 1);
suf -= suff.kth (k - f);
f ++;
if (i >= f && n - i >= k - f) ans = min (ans, max (pre, suf));
cur = max (pre, suf);
}
if (i == n) break;
pref.ins (a[i + 1]), sizp ++;
if (pref.rank (a[i + 1]) <= f) pre += a[i + 1], pre -= pref.kth (f + 1);
int awa = 0;
if (suff.rank (a[i + 1]) <= k - f) suf -= a[i + 1], awa = 1;
suff.del (a[i + 1]), sizs --;
if (awa) suf += suff.kth (k - f);
}
while (sizp --) pref.del (pref.kth (1));
while (sizs --) suff.del (suff.kth (1));
printf ("%lld\n", ans);
}
return 0;
}
// Always keep it simple and stupid
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下