2023 国际大学生程序设计竞赛亚洲区域赛(济南站)(SMU Autumn 2024 Team Round 2)
I. Strange Sorting
思路
代码
查看代码
#include
#define ll __int128
#define int long long
#define double long double
#define PII pair
using namespace std;
const int N = 2E5 + 3;
#define endl '\n'
void solve() {int n;cin >> n;vectora(n);for (int i = 0; i < n ; ++i) {cin >> a[i];}int ans = 0;vectorres;for (int i = 0; i < n ; ++i) {if (a[i] == i + 1)continue;int r = -1;for (int j = i + 1; j < n ; ++j) {if (a[j] < a[i]) {r = j;}}if (r == -1)break;ans++;res.push_back({i + 1, r + 1});sort(a.begin() + i, a.begin() + r + 1);}cout << ans << endl;for (auto [x, y] : res) {cout << x << ' ' << y << endl;}
}
int32_t main() {ios::sync_with_stdio(false);cin.tie(0);int T = 1;cin >> T;while (T--) {solve();}return 0;
}
D. Largest Digit
思路
代码
查看代码
#include
#define ll __int128
#define int long long
#define double long double
#define pb push_back
#define arr array
#define PII pair
#define endl '\n'
using namespace std;
int n, k, m, s;
vectorans;
int faa(int x) {string ss = to_string(x);int mx = 0;for (int i = 0; i < ss.length(); i++) {mx = max(mx, (int)(ss[i] - '0'));}return mx;
}
void solve() {int l1, l2, r1, r2;cin >> l1 >> r1 >> l2 >> r2;if (r1 - l1 + 1 >= 10 || r2 - l2 + 1 >= 10) {cout << 9 << endl;} else {int mx = 0;for (int i = l1; i <= r1; i++) {for (int j = l2; j <= r2; j++) {mx = max(mx, faa(i + j));}}cout << mx << endl;}
}
int32_t main() {std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int T = 1;cin >> T;while (T--) {solve();}return 0;
}
A. Many Many Heads
思路
代码
查看代码
#include
#define ll __int128
//#define int long long
#define double long double
#define pb push_back
#define arr array
//#define double long double
#define PII pair
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, mod = 998244353;
const int L = 2015;
int a[N], vis[1003][1003], b[N];
int n, k, m, s;
vectorans;
string s1;
vectoranss;
void solve() {cin >> s1;n = s1.length();int summ = 0;for (int i = 1; i <= n; i++) {char x = s1[i - 1];if (x == '(' || x == ')') {a[i] = 0;} else {a[i] = 1;}summ += a[i];}if (n <= 4) {if (n == 2) {cout << "Yes\n";} else {if (summ != 0 && summ != 4) {cout << "Yes\n";} else {cout << "No\n";}}return;}int l = 1, ls = 1, lls = 1;int ff = 1;int t[2] = {0, 0};for (int i = 1; i <= n; i++) {if (i > 1) {if (a[i] == a[i - 1]) {l++;} else {if (l > 1) {if (a[i - 1] == '(' || a[i - 1] == ')') {t[0]++;} else {t[1]++;}}if (l > 2) {ff = 0;}if (l == 2 && ls == 2) {ff = 0;}if (l == 2 && lls == 2 && ls % 2 == 0) {ff = 0;}lls = ls;ls = l;l = 1;}}}if (l > 1) {if (a[n] == '(' || a[n] == ')') {t[0]++;} else {t[1]++;}}if (l > 2 || t[0] > 2 || t[1] > 2) {ff = 0;}if (l == 2 && ls == 2) {ff = 0;}if (ff) {cout << "Yes\n";} else {cout << "No\n";}
}
int32_t main() {std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int T = 1;cin >> T;while (T--) {solve();}return 0;
}
G. Gifts from Knowledge
思路
队友当时写的二分图染色,然后一直WA,我是写的种类并查集维护集合的相同与相反,我后来也写了一发二分图染色,还是WA,估计是因为二分图染色不好维护集合的相同情况,哎哎不懂。
代码
查看代码
#include
using namespace std;
using i64 = long long;
constexpr i64 mod = 1000000007;
i64 ksm(i64 a, i64 n) {
i64 ans = 1;
while (n) {
if (n & 1)
ans = (ans * a) % mod;
a = a * a % mod;
n >>= 1;
}
return ans % mod;
}struct UFS {
int sz;
vectorrank, p;
UFS(int n) {
sz = n;
rank.resize(n + 1);
p.resize(n + 1);
for (int i = 0; i <= sz; i++) {
p[i] = i;
rank[i] = 0;
}
}
void link(int x, int y) {
if (x == y)
return;
if (rank[x] > rank[y])
p[y] = x;
else
p[x] = y;
if (rank[x] == rank[y])
rank[y]++;
}
int find(int x) {
return x == p[x] ? x : (p[x] = find(p[x]));
}
void unin(int x, int y) {
link(find(x), find(y));
}
void compress() {
for (int i = 0; i < sz; i++)
find(i);
}
};void solve() {
int n, m; cin >> n >> m;vector has(m, vector<int>()); vector<string> s(n + 1); for (int i = 1; i <= n; i ++) {cin >> s[i];for (int j = 0; j < m; j ++) {if (s[i][j] == '1') {has[j].push_back(i);}} }if ((m & 1) && has[m / 2].size() > 1) {cout << 0 << '\n';return ; }UFS ufs(2 * n + 1); for (int i = 0; i < m / 2; i ++) {if (has[i].size() + has[m - i - 1].size() > 2) {cout << 0 << '\n';return ;} else if (has[i].size() + has[m - i - 1].size() != 2) {continue;}if (has[i].size() == 2) {int u = has[i][0], v = has[i][1];ufs.unin(u, v + n);ufs.unin(u + n, v);} else if (has[m - i - 1].size() == 2) {int u = has[m - i - 1][0], v = has[m - i - 1][1];ufs.unin(u, v + n);ufs.unin(u + n, v);} else {int u = has[i][0], v = has[m - i - 1][0];ufs.unin(u, v);ufs.unin(u + n, v + n);} }int res = 0; for (int i = 1; i <= 2 * n; i ++) {if (i <= n && ufs.find(i) == ufs.find(i + n)) {cout << 0 << '\n';return ;}if (ufs.find(i) == i) {res ++;} }cout << ksm(2, res / 2) << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);int t; cin >> t;while (t--) {solve(); }return 0;
}
K. Rainbow Subarray
思路
和题解类似,不过我们是用主席树维护的中位数。
代码
查看代码
#include
#define ll long long
#define int long long
#define double long double
#define PII pair
using namespace std;
const int mod = 1e9 + 7;
#define endl '\n'
using namespace std;
#define lc p<<1
#define rc p<<1|1
const int N = 500002;
int n, q, m, cnt = 0;
ll a[N], b[N], T[N];
int sum[N << 5], L[N << 5], R[N << 5];
int c[N];
inline int build(int l, int r)
{int rt = ++ cnt;sum[rt] = 0;if (l < r) {L[rt] = build(l, l + r >> 1);R[rt] = build((l + r >> 1) + 1, r);}return rt;
}
inline int update(int pre, int l, int r, int x)
{int rt = ++ cnt;L[rt] = L[pre]; R[rt] = R[pre]; sum[rt] = sum[pre] + 1;if (l < r) {if (x <= (l + r >> 1)) L[rt] = update(L[pre], l, (l + r >> 1), x);else R[rt] = update(R[pre], (l + r >> 1) + 1, r, x);}return rt;
}
inline int query(int u, int v, int l, int r, int k)
{if (l >= r) return l;int x = sum[L[v]] - sum[L[u]];if (x >= k) return query(L[u], L[v], l, (l + r >> 1), k);else return query(R[u], R[v], (l + r >> 1) + 1, r, k - x);
}
int w[N];
struct node {int l, r;ll sum;int cnt;
} tr[N << 2];
void push_up(int p) {tr[p].cnt = tr[lc].cnt + tr[rc].cnt;tr[p].sum = tr[lc].sum + tr[rc].sum;
}
void build(int p, int l, int r) {tr[p] = {l, r, 0};if (l == r) {tr[p] = {l, r, 0, 0}; return;}int mid = (l + r) >> 1;build(lc, l, mid);build(rc, mid + 1, r);push_up(p);
}
void update(int p, int x, int k) {if (tr[p].l == x and tr[p].r == x) {tr[p].cnt += k;tr[p].sum = tr[p].cnt * b[x];return;}int mid = tr[p].l + tr[p].r >> 1;if (x <= mid)update(lc, x, k);if (x > mid)update(rc, x, k);push_up(p);
}
int query(int p, int x, int y) {if (x <= tr[p].l and tr[p].r <= y) {return tr[p].sum;}int mid = tr[p].l + tr[p].r >> 1;ll sum = 0;if (x <= mid) {sum += query(lc, x, y);}if (y > mid) {sum += query(rc, x, y);}return sum;
}
int querycnt(int p, int x, int y) {if (x <= tr[p].l and tr[p].r <= y) {return tr[p].cnt;}int mid = tr[p].l + tr[p].r >> 1;int sum = 0;if (x <= mid) {sum += querycnt(lc, x, y);}if (y > mid) {sum += querycnt(rc, x, y);}return sum;
}
void solve() {cnt = 0;ll k;cin >> n >> k;for (int i = 1; i <= n ; ++i) {cin >> a[i];a[i] -= i;b[i] = a[i];}sort(b + 1, b + 1 + n);m = unique(b + 1, b + 1 + n) - b - 1;cnt = 0;T[0] = build(1, m);for (int i = 1; i <= n; i ++) {int t = lower_bound(b + 1, b + 1 + m, a[i]) - b;c[i] = t;T[i] = update(T[i - 1], 1, m, t);}auto check = [&](int x, int l) {int st = 0;int zj = (x + 1) / 2;for (int i = l; i <= n ; ++i) {update(1, c[i], 1);if (i < x)continue;else if (i > x) {update(1, c[i - x], -1);}int l = i - x + 1;int r = i;int t = query(T[l - 1], T[r], 1, m, zj);int zws = b[t];ll sum = zws * querycnt(1, 1, t) - query(1, 1, t) + query(1, t, m) - zws * querycnt(1, t, m);if (sum <= k) {st = 1;}}for (int i = n - x + 1; i <= n ; ++i) {update(1, c[i], -1);}return st;};int r = 1;int res = 0;vectorvis(n + 1);for (int l = 1; l <= n ; ++l) {int st = 1;while (r <= n and st) {if (vis[r] == 0) {update(1, c[r], 1);vis[r] = 1;}int x = r - l + 1;int zj = (x + 1) / 2;int t = query(T[l - 1], T[r], 1, m, zj);int zws = b[t];ll sum = zws * querycnt(1, 1, t) - query(1, 1, t) + query(1, t, m) - zws * querycnt(1, t, m);if (sum > k) {st = 0;} else {r++;res = max(res, x);}}update(1, c[l], -1);}cout << res << endl;
}
int32_t main() {ios::sync_with_stdio(false);cin.tie(0);int TT = 1;cin >> TT;build(1, 1, 500000);while (TT--) {solve();}return 0;
}