A - Special Permutation
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n;
rep (i, 2, n) cout << i << ' '; cout << "1
";
}
return 0;
}
B - Unique Bid Auction
stl 模拟
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n;
map<int, int> a; set<int> b;
rep (i, 1, n) {
cin >> m;
if (b.count(m)) continue;
else if (a.count(m)) b.insert(m), a.erase(m);
else a[m] = i;
}
if (!a.empty()) cout << (*a.begin()).se << '
';
else cout << "-1
";
}
return 0;
}
C - Sequence Transformation
模拟
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n;
vector<vector<PII>> a(n + 1);
rep (i, 1, n) {
cin >> b[i];
if (b[i] == b[i - 1]) ++a[b[i]].back().se;
else a[b[i]].pb({ i, i });
}
int ans = 2e9;
for (auto &i : a) if (!i.empty()) umin(ans, i.size() + 1 - (i[0].fi == 1) - (i.back().se == n));
cout << ans << '
';
}
return 0;
}
E - Number of Simple Paths
基环树, 子树节点 互相到达, 不同子树之间有两条路相互到达
int main() {
IOS;
for (cin >> _; _; --_) {
ll n; cin >> n; tot = 0;
rep (i, 1, n) h[i] = deg[i] = 0, sz[i] = 1;
rep (i, 1, n) {
int u, v; cin >> u >> v;
add(u, v); add(v, u); ++deg[u], ++deg[v];
}
queue<int> q;
rep (i, 1, n) if (deg[i] == 1) q.push(i);
while (!q.empty()) {
int x = q.front(); q.pop();
for (int i = h[x]; i; i = ne[i]) {
int y = to[i];
if (deg[y] == 1) continue;
if (--deg[y] == 1) q.push(y);
sz[y] += sz[x];
}
}
ll ans = (ll)n * (n - 1);
rep (i, 1, n) if (deg[i] == 2) ans -= (ll)sz[i] * (sz[i] - 1) / 2;
cout << ans << "
";
}
return 0;
}
F
我看榜一是 stl 做的, 大家有兴趣可以看下一
我是线段树 + 倍增
线段树维护的是区间最小值
预处理 mx[i] 表示 (i ~ n) 的最大值
从左往右枚举 x, 再倍增y,
复杂度 (nlog^2n)
struct BIT {
static const int N = 2e5 + 5;
struct node {
int l, r, val;
} tr[N << 2];
void build(int rt, int l, int r, int *a) {
tr[rt].l = l, tr[rt].r = r;
if (l == r) { tr[rt].val = a[l]; return; }
int mid = l + r >> 1;
build(rt << 1, l, mid, a); build(rt << 1 | 1, mid + 1, r, a);
tr[rt].val = min(tr[rt << 1].val, tr[rt << 1 | 1].val);
}
int ask(int rt, int l, int r) {
if (tr[rt].l >= l && tr[rt].r <= r) return tr[rt].val;
int ans = 2e9, mid = tr[rt].l + tr[rt].r >> 1;
if (mid >= l) umin(ans, ask(rt << 1, l, r));
if (r > mid) umin(ans, ask(rt << 1 | 1, l, r));
return ans;
}
} bit;
const int N = 2e5 + 5;
int n, m, _, k;
int a[N], mx[N];
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n; mx[n + 1] = m = k = 0;
rep (i, 1, n) cin >> a[i];
bit.build(1, 1, n, a);
per (i, n, 1) mx[i] = max(mx[i + 1], a[i]);
rep (i, 1, n) {
umax(m, a[i]);
if (mx[i + 2] < m) break;
k = i;
per (j, 17, 0) {
int c = k + (1 << j);
if (c < n && mx[c + 1] >= m && bit.ask(1, i + 1, c) >= m) k = c;
}
if (k > i && mx[k + 1] == m && bit.ask(1, i + 1, k) == m) { m = i; break; }
else k = 0;
}
if (k) cout << "YES
" << m << ' ' << k - m << ' ' << n - k << '
';
else cout << "NO
";
}
return 0;
}