2023 國際大學生程式設計競賽亞洲區域賽(濟南站)(SMU Autumn 2024 Team Round 2)

Ke_scholar發表於2024-11-03

2023 國際大學生程式設計競賽亞洲區域賽(濟南站)(SMU Autumn 2024 Team Round 2)

I. Strange Sorting

思路

image

image

程式碼

檢視程式碼
#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

思路

image

程式碼

檢視程式碼
#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

思路

image

程式碼

檢視程式碼
#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

思路

image

image

隊友當時寫的二分圖染色,然後一直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;
vector 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 
#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>

相關文章