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<nt,int>
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;
} <int>
D. Largest Digit
思路
程式碼
檢視程式碼
#include
#define ll __int128
#define int long long
#define double long double
#define pb push_back
#define arr array<nt,3>
#define PII pair<nt,int>
#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;
} <int><t,3>
A. Many Many Heads
思路
程式碼
檢視程式碼
#include
#define ll __int128
//#define int long long
#define double long double
#define pb push_back
#define arr array<nt,3>
//#define double long double
#define PII pair<nt,int>
#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;
} <int><t,3>
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<nt,int>
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;
} <int>