2025.8.28 Codeforces Round 1046 (Div. 1)
A. Against the Difference
题意
给一个序列,求其最长的可以分割成若干段 \([x,x,\dots,x]\)(\(x\) 个 \(x\))的子序列。
题解
预处理每个数的出现位置 \(p_{x,i}\),以及每个数是第几次出现的 \(o_i\)。dp 设 \(f(i)\) 为前 \(i\) 个数能取出的最长子序列,则
const int N = 2e5+5;
int n, a[N], o[N], f[N];
vector <int> p[N];
void solve(){
cin >> n;
for (int i=1; i<=n; ++i) p[i].clear();
for (int i=1; i<=n; ++i)
{
cin >> a[i];
p[a[i]].push_back(i);
o[i] = p[a[i]].size();
}
for (int i=1; i<=n; ++i)
{
f[i] = f[i-1];
if (o[i] >= a[i]) f[i] = max(f[i], f[p[a[i]][o[i] - a[i]] - 1] + a[i]);
}
cout << f[n] << '\n';
}
B. For the Champion
题意
交互题。已知 \(n\) 个点 \((x_i, y_i)\),你初始位于 \((X,Y)\)。
每次询问可以让自己向上下左右任意方向移动不超过 \(10^9\) 个单位,交互器会返回当前距离给定的 \(n\) 个点最近的曼哈顿距离 \(\min_{i=1}^n (|x-x_i| + |y-y_i|)\)。
最多 \(10\) 次询问,求 \(X,Y\) 的值。所有坐标均在 \([-10^9, 10^9]\) 之间。
题解
主要思路就是想办法把绝对值去掉。首先尽量往左下走:向左走 \(2\times 10^9\) 步,再向下走 \(2\times 10^9\) 步。这样就一定有 \(x<x_i, y<y_i\)。于是可以反推出 \(X+Y\)。
再尽量往右下走:在上面的基础上向右走 \(4\times 10^9\) 步。这样就一定有 \(x>x_i, y<y_i\),可以反推出 \(X-Y\)。
直接解出 \(X,Y\) 即可。询问次数为固定的 \(8\) 次。
ll ask(char op, ll k)
{
cout << "? " << op << ' ' << k << endl;
cout.flush();
ll res; cin >> res;
return res;
}
const ll M = 1e9;
ll x, y, A, B, C, D;
void solve(){
int n; cin >> n;
A = B = 2e9;
for (int i=1; i<=n; ++i)
{
cin >> x >> y;
A = min(A, x+y);
B = min(B, y-x);
}
ask('L', M);
ask('L', M);
ask('D', M);
C = ask('D', M);
ask('R', M);
ask('R', M);
ask('R', M);
D = ask('R', M);
C = A - C + 4*M;
D = B - D + 4*M;
x = (C - D) / 2;
y = (C + D) / 2;
cout << "! " << x << ' ' << y << endl;
cout.flush();
}
C. By the Assignment
题意
给一张无向带点权图,某些点点权未知,要使任意点对 \((x,y)\) 都满足以 \(x\) 为起点 \(y\) 为终点的所有简单路径的异或和相等,点权范围 \([0, V)\),求方案数。
题解
观察样例猜结论,归纳证明,可以得到:奇环上的所有点权必须为 0,偶环上的所有点权必须相等。
进而可知大小超过 2 的 bcc 中所有点权必须相等,且是否必须为 0 取决于能否二分图染色。
tarjan + 并查集,判掉原本就不合法的情况后容易维护出自由元的数量 \(s\),最后答案即为 \(V^s\)。
const int N = 2e5+5, M = 4e5+5;
int n, m, k, x[M], y[M], a[N];
vector <vector<pii>> e;
struct node_bcc
{
int n, id, tp, bcc_n;
vector<vector<pair<int, int>>> e;
vector<vector<int>> bcc_node, bcc_edge;
vector<int> dfn, low, st, ed, blk, ct;
node_bcc(const vector<vector<pair<int, int>>> &e, int m) :
n(e.size()), id(0), tp(0), bcc_n(0), e(e), dfn(n, -1), low(n, -1), st(m), ed(m), blk(m), ct(n)
{
for (int i = 0; i < n; i++) for (auto [v, w] : e[i])
{
assert(v >= 0 && v < n);
assert(w >= 0 && w < m);
}
for (int i = 0; i < n; i++) if (dfn[i] == -1) dfs(i, 1);
bcc_node.resize(bcc_n);
for (int i = 0; i < n; i++) for (auto [v, w] : e[i]) bcc_node[blk[w]].push_back(i);
vector<int> flg(n);
for (auto &v : bcc_node)
{
vector<int> t;
for (int x : v) if (!exchange(flg[x], 1)) t.push_back(x);
swap(t, v);
for (int x : v) flg[x] = 0;
}
for (int i = 0; i < n; i++) if (e[i].size() == 0)
{
bcc_node.push_back({i});
bcc_edge.push_back({ });
++bcc_n;
}
}
void dfs(int u, bool rt)
{
dfn[u] = low[u] = id++;
int cnt = 0;
for (auto [v, w] : e[u]) if (!ed[w])
{
st[tp++] = w;
ed[w] = 1;
if (dfn[v] == -1)
{
dfs(v, 0);
++cnt;
cmin(low[u], low[v]);
if (dfn[u] <= low[v])
{
ct[u] = cnt > rt;
bcc_edge.push_back({ });
do
{
bcc_edge[bcc_n].push_back(st[--tp]);
blk[st[tp]] = bcc_n;
} while (st[tp] != w);
++bcc_n;
}
}
else cmin(low[u], dfn[v]);
}
}
};
int col[N];
bool fl;
vector <int> g[N];
void dfs(int u, int f)
{
for (int v : g[u]) if (v != f)
{
if (col[v] == col[u]) fl = 1;
else if (!col[v]) col[v] = -col[u], dfs(v, u);
}
}
int f[N];
int find(int x)
{
return x == f[x] ? x : f[x] = find(f[x]);
}
bool merge(int x, int y)
{
x = find(x), y = find(y);
if (x == y) return 1;
if (~a[x] && ~a[y] && a[x] != a[y]) return 0;
if (~a[x]) a[y] = a[x];
else if (~a[y]) a[x] = a[y];
f[y] = x;
return 1;
}
ll solve(){
cin >> n >> m >> k; e.clear(); e.resize(n);
for (int i=0; i<n; ++i) cin >> a[i], f[i] = i;
for (int i=0; i<m; ++i)
{
cin >> x[i] >> y[i]; --x[i], --y[i];
e[x[i]].push_back({y[i], i});
e[y[i]].push_back({x[i], i});
}
node_bcc bcc(e, m);
for (int i=0; i < bcc.bcc_n; ++i)
{
if (bcc.bcc_node[i].size() <= 2) continue;
int st = bcc.bcc_node[i][0];
for (int u : bcc.bcc_node[i])
{
if (!merge(u, st)) return 0;
}
for (int j : bcc.bcc_edge[i])
{
g[x[j]].push_back(y[j]);
g[y[j]].push_back(x[j]);
}
fl = 0, col[st] = 1, dfs(st, 0);
for (int u : bcc.bcc_node[i]) g[u].clear(), col[u] = 0;
if (fl)
{
int& val = a[find(st)];
if (val > 0) return 0;
val = 0;
}
}
int ans = 0;
for (int i=0; i<n; ++i) if (a[i] == -1 && f[i] == i) ++ans;
return qpow(k, ans);
}

浙公网安备 33010602011771号