2023 国际大学生程序设计竞赛亚洲区域赛(济南站)(SMU Autumn 2024 Team Round 2)

2023 国际大学生程序设计竞赛亚洲区域赛(济南站)(SMU Autumn 2024 Team Round 2)

I. Strange Sorting

思路

image

image

代码

#include <bits/stdc++.h>
#define ll __int128
#define int long long
#define double long double
#define PII pair<int,int>
using namespace std;
const int N = 2E5 + 3;
#define endl '\n'
void solve() {
    int n;
    cin >> n;
    vector<int>a(n);
    for (int i = 0; i < n ; ++i) {
        cin >> a[i];
    }
    int ans = 0;
    vector<PII>res;
    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

思路

image

代码

#include <bits/stdc++.h>
#define ll __int128
#define int long long
#define double long double
#define pb push_back
#define arr array<int,3>
#define PII pair<int,int>
#define endl '\n'
using namespace std;
int n, k, m, s;
vector<PII>ans;
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

思路

image

代码

#include <bits/stdc++.h>
#define ll __int128
//#define int long long
#define double long double
#define pb push_back
#define arr array<int,3>
//#define double long double
#define PII pair<int,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;
vector<PII>ans;
string s1;
vector<PII>anss;
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

思路

image

image

队友当时写的二分图染色,然后一直WA,我是写的种类并查集维护集合的相同与相反,我后来也写了一发二分图染色,还是WA,估计是因为二分图染色不好维护集合的相同情况,哎哎不懂。

代码

#include <bits/stdc++.h>
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;
	vector<int> rank, 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

思路

和题解类似,不过我们是用主席树维护的中位数。

image

代码

#include <bits/stdc++.h>
#define ll long long
#define int long long
#define double long double
#define PII pair<int,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;
    vector<int>vis(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;
}
posted @ 2024-11-03 16:36  Ke_scholar  阅读(2)  评论(0编辑  收藏  举报