首页 > 其他分享 >The 3rd Universal Cup. Stage 18: Southeastern Europe

The 3rd Universal Cup. Stage 18: Southeastern Europe

时间:2024-11-25 13:22:47浏览次数:5  
标签:Europe info return cur 3rd Cup int i32 using

A. All-Star

每次操作至多可以把一个点插在根上,因此选择度数最多的点插在根上,然后根据深度标记边的方向。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;

using vi = vector<int>;
using pii = pair<int,int>;

i32 main(){
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int n;
	cin >> n;

	vector<vi> e(n + 1);
	for(int i = 1, x, y; i < n; i ++) 
		cin >> x >> y, e[x].push_back(y), e[y].push_back(x);
	
	int root = 1;
	for(int i = 2; i <= n; i ++) 
		if(e[i].size() > e[root].size()) root = i;

	vi vis(n + 1);
	vector<pii> res;
	queue<int> q;

	q.push(root), vis[root] = 1;
	while(not q.empty()) {
		int x = q.front();
		q.pop();
		for(auto y : e[x]) {
			if(vis[y]) continue;
			q.push(y), vis[y] = 1;
			if(x != root) res.emplace_back(x, y);
		}
	}
	cout << res.size() << "\n";
	for(auto [x, y] : res)
		cout << root << " " << x << " " << y << "\n";
	return 0;
}

D. Donkey and Puss in Boots

对于后手来说,只要剩下的石子总和大于\(n\) 就一定可以进行一次操作,并且一次操作把所有的石子全部取完。因此先手要做的就是通过一步操作使得石子总和小于\(n\)。因此先手有一定会选择最多的一堆石子。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;


using vi = vector<i64>;


i32 main(){
	ios::sync_with_stdio(false), cin.tie(nullptr);
	i64 n;
	cin >> n;
	vi a(n);
	for(auto &i : a) cin >> i;
	if (std::count(a.begin(), a.end(), 0) == n){
		std::cout << "Puss in Boots\n";
		return 0;
	}
	if(accumulate(a.begin(), a.end(),0ll) - ranges::max(a) < n) 
		cout << "Donkey";
	else cout << "Puss in Boots";
	return 0;
}

G. Shrek's Song of the Swamp

简单的 dp,记录一下上一次出现的位置就好了。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;

using vi = vector<int>;
using pii = pair<int,int>;

i32 main(){
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int n;
	cin >> n;
	
	vi a(n + 1), lst(n + 1);
	map<int,int> vis;
	for(int i = 1; i <= n; i ++) {
		cin >> a[i];
		lst[i] = vis[a[i]], vis[a[i]] = i;
	}
	vi f(n + 1);
	for(int i = 1, j; i <= n ; i ++) {
		f[i] = f[i - 1], j = lst[i];
		if(j - 1 >= 0) f[i] = max({f[i], f[j - 1] + 2, f[j] + 1});
	}
	cout << f[n] << "\n";
	return 0;
}

H. Shreckless

贪心考虑要给每行至少安排一个逆序对,我们给每一列从大到小排序。然后从后向前贪心考虑相邻的两列,可以构成的逆序对的个数。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;

using vi = vector<int>;


void solve(){
	int n, m;
	cin >> m >> n;
	
	vector a(n, vi(m));

	for(int i = 0; i < m; i ++) 
		for(int j = 0; j < n; j ++)
			cin >> a[j][i];

	for (int i = 0; i < n; ++i) ranges::sort(a[i], greater<>());

	int l = 0, r, cnt = 0;
	for (int i = n - 1; i > 0; --i) {
		r = l, l = 0;
		for (int j = r; j < m; ++j) {
			if (a[i][j] < a[i - 1][l]) {
				l ++, cnt ++;
			}
		}
	} 
	if (cnt >= m) cout << "YES\n";
	else cout << "NO\n";
	
	
}

i32 main(){
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int T;
	cin >> T;
	while(T --) solve();
	return 0;
}

J. Make Swamp Great Again

如果三元组有两个数是目标数,就可以一次操作把三元组中所有的数变为目标数。

如果三元组中目标数是最大值或最小值,需要两次操作就能三元组中所有数变为目标数。

如果三元组中目标数既不是最大值,也不是最小值,需要三次操作才能三元组中所有数变为目标数。

因此要统计不是目标数的个数,并且检查目标数是否在某一个三元组出现两次或是某个三元组的最大或最小值。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;

using vi = vector<int>;



i32 main(){
	ios::sync_with_stdio(false), cin.tie(nullptr);
	int n;
	cin >> n;

	map<int,vi> pos;
	vi a(n);

	for(int i = 0, x; i < n; i ++) 
		cin >> a[i], pos[a[i]].push_back(i);

	for(int i = 0, ret, f; i < n; i ++) {
		ret = n - pos[a[i]].size(), f = 1;
		for(auto j : pos[a[i]]){
			if(f == 0) break;
			for(int l = j - 2; l <= j and f; l ++) {
				if(max({a[(l + n) % n], a[(l + 1 + n) % n], a[(l + 2 + n) % n]}) == a[j]) f = 0;
				if(min({a[(l + n) % n], a[(l + 1 + n) % n], a[(l + 2 + n) % n]}) == a[j]) f = 0;
			}
		}
		cout << ret + f << " ";
	}
	return 0;
}

K. Intrusive Donkey

我们用线段树可以维护出每一个字母出现次数。对于修改操作\([l,r]\),实际上我们可以通过在前缀和上二分来快速定位左右端点对应的字母。并且每次操作至多会有两个字母是没有被完全包围的。因此我们可以用单点加法和区间乘法来实现修改。查询操作也是用在前缀和上二分实现。

#include <bits/stdc++.h>

using namespace std;


using i32 = int32_t;
using i64 = long long;

const i32 inf = INT_MAX / 2;
const i64 INF = LLONG_MAX / 2;

struct Info{
	i64 value, mul;

	Info(i64 value = 0) : value(value) {
		mul = 1;
	}

	i64 val() const {
		return value * mul;
	}

	Info operator+(const Info &b) {
		Info ret;
		ret.value = val() + b.val();
		ret.mul = 1;
		return ret;
	}
};

struct Node {
	i32 l, r;
	Info info;
	Node *left, *right;

	Node(i32 p, i64 v = 1) : info(v) {
		l = r = p;
		left = right = nullptr;
	}

	Node(i32 l, i32 r, Node *left, Node *right) 
		: l(l), r(r), left(left), right(right) {
		info = left -> info + right -> info;
	}

};

void maintain(Node *cur) {
	if(cur -> left == nullptr) return;
	cur -> info = cur -> left -> info + cur -> right -> info;
	return;
}

void pushdown(Node *cur) {
	if(cur -> info.mul == 1) return;
	cur -> info.value *= cur -> info.mul;
	if(cur -> left != nullptr) {
		cur -> left -> info.mul *= cur -> info.mul;
		cur -> right -> info.mul *= cur -> info.mul;
	}
	cur -> info.mul = 1;
	return;
}

Node *build(i32 l, i32 r) {
	if(l == r) return new Node(l);
	i32 mid = (l + r) / 2;
	auto left = build(l, mid) , right = build(mid + 1, r);
	return new Node(l, r, left, right);
}

Info query(i32 l, i32 r, Node *cur) {
	if(cur == nullptr) return Info();
	if(cur -> r < l or cur -> l > r) return Info();
	if(l <= cur -> l and cur -> r <= r) return cur -> info;
	pushdown(cur);
	return query(l, r, cur -> left) + query(l, r, cur -> right);
}

i64 pre(i32 i, Node *cur) {
	return query(1, i, cur).val();
}


void update_add(i32 p, i64 x, Node *cur) {
	if(cur == nullptr) return;
	if(p > cur -> r or p < cur -> l) return;
	pushdown(cur);
	if(p == cur -> l and cur -> r == p) {
		cur -> info.value += x;
		return;
	}
	update_add(p, x, cur -> left), update_add(p, x, cur -> right);
	maintain(cur);
	return;
}

void modify_mul(i32 l, i32 r, i64 x, Node *cur) {
	if(cur == nullptr) return;
	if(l > cur -> r or r < cur -> l) return;
	pushdown(cur);
	if(l <=cur -> l and cur -> r <= r) {
		cur -> info.mul *= x;
		return;
	}
	modify_mul(l, r, x, cur -> left), modify_mul(l, r, x, cur  -> right);
	maintain(cur);
	return;
} 


i32 upper(i64 x, Node *cur){
	if(cur -> l == cur -> r) return cur -> l;
	pushdown(cur);
	if(cur -> left -> info.val() < x) {
		x -= cur -> left -> info.val();
		return upper(x, cur -> right);
	} else {
		return upper(x, cur -> left);
	}
}

i32 main() {
	ios::sync_with_stdio(false), cin.tie(nullptr);

	int n, q;
	cin >> n >> q;

	string s;
	cin >> s;
	s = " " + s;

	auto root = build(1, n);

	while(q --) {
		int op;
		cin >> op;
		if(op == 1) {
			i64 l, r;
			cin >> l >> r;
			i32 idxl = upper(l, root);
			i32 idxr = upper(r, root);
			if(idxl != idxr) {
				i64 addl = pre(idxl, root) - l + 1;
				i64 addr = query(idxr, idxr, root).val() - (pre(idxr, root) - r);
				update_add(idxr, addr, root);
				if(idxl + 1 <= idxr - 1) {
					modify_mul(idxl + 1, idxr - 1, 2, root);
				}
				update_add(idxl, addl, root);
			} else {
				update_add(idxl, r - l + 1, root);
			}
		} else {
			i64 x;
			cin >> x;
			cout << s[upper(x, root)] << "\n";
		}
	}
	return 0;
}

标签:Europe,info,return,cur,3rd,Cup,int,i32,using
From: https://www.cnblogs.com/PHarr/p/18565829

相关文章

  • 103rd 2024/9/24 斜率优化
    总算是补上了很久之前的坑,一直没学,之前一直不肯动脑子?思路可以从简单的进行入手对于部分DP,若转移是\(i\)从一个\(j\)转移过来,且转移具有单调性,切极为明显,形如\(f_i=max(f_i,f_j+b_j+a_i)\)那么显然可以直接求之前的最值,用一个max记录即可但是有时候会出现跟双方都有关的贡献项......
  • The 2023 ICPC Asia Hangzhou Regional Contest (The 2nd Universal Cup. Stage 22: H
    The2023ICPCAsiaHangzhouRegionalContest(The2ndUniversalCup.Stage22:Hangzhou)M.V-Diagram题意:给定一个“v图”,求平均值最大的子"v图"思路:原图的最低点以及左右两个点必须取,如何先取满左边或者右边在贪心即可voidsolve(){lln;cin>>n;vect......
  • The 3rd Universal Cup. Stage 8: Cangqian
    Preface战术最失败的一集,徐神从开场就被模拟题关住了,直到4h30min的时候才放出来然后剩下的题也开的不顺,最后感觉好多题都没写就7题下班了这场也是延续了之前几场的一贯画风,最后1h我在狂暴鸿儒一个题,然后挂飞了也没过,赛后稍微一想就发现又犯了个唐氏错误A.Bingo沟槽的......
  • TICUP_ALL 开源项目教程
    TICUP_ALL开源项目教程引言在当今的软件开发领域,开源项目已经成为推动技术进步和创新的重要力量。TICUP_ALL是一个新兴的开源项目,旨在为开发者提供一个全面的工具包,帮助他们更高效地构建和管理复杂的软件系统。本文将详细介绍TICUP_ALL开源项目的背景、功能、安装步骤、使用方......
  • The 1st Universal Cup. Stage 19: America
    Preface中秋加训,发现Ucup里好多比赛要么之前做过,要么就是太毒瘤(有场比赛直接把模\(998244353\)写在题目名里了),因此就直接跳到这场北美区决赛了这场前期因为卡题意以及卡签到打的还是挺难受的,不过好在恶心归恶心题目还是都能出,最后也是堪堪写了9题由于这场没找到题解(其实......
  • ucup 做题记录
    ucup做题记录https://www.cnblogs.com/yhddd/p/18415768The3rdUniversalCup.Stage1:St.PetersburgAbitset维护\(f_{i,j}=a_i<a_j\)。每\(m\)个点划一个段,统计跨过段的答案,维护一段的后缀or。C从大往小加,线段树维护区间前缀后缀和最大连续\(1\)。D在\(0\)......
  • The 3rd Universal Cup. Stage 7: Warsaw 补题
    A太牛了。复读jiangly题解。先把代价除以二。设\(f_{i,j}\)表示以\(j\)的代价覆盖前\(i\)个点最多还能覆盖多少距离。发现只有\(f_{i,x},f_{i,x+1},f_{i,x+2}\)的值是有意义的。其中\(x\)为覆盖的最小代价。因为\(f_{i,x+3}\)一定不优。不如你到下个点再买一张......
  • The 3rd Universal Cup. Stage 9: Xi'an
    A.AnEasyGeometryProblem差分之后条件相当于类似\(a_{i-1}+a_i=k+b\)且\(a_{i-r+1}+a_{i+r}=k\)的条件,线段树维护\(a_i\)和\(k-a_{n-i}\)的哈希值,查询直接二分即可。时间复杂度\(O(n+q\log^2n)\)。B.CountingMultisets考虑\(p(S)\)......
  • The 3rd Universal Cup. Stage 8: Cangqian
    C.ChallengeNPC考虑构造一个二分图,左边是\(1,3,5,7\)右侧是\(2,4,6,8\)。最优解肯定是一边全1,一边全2。如果\(1,2\)之间不连边,这\(2\)就会被染色为1,因此只要让\(2,3\)连边,\(3\)会被染色为\(2\),然后\(1,4\)连边,\(4\)也会被染色为\(5\),这时只要让\(2,5\)和\(4,5\)连边,\(5\)就......
  • The 3rd Universal Cup. Stage 8: Cangqian
    题解:https://files.cnblogs.com/files/clrs97/ZJCPC24_Tutorial.pdf Code:A.Bingo#include<bits/stdc++.h>usingnamespacestd;stringn;intm;typedeflonglongll;llsum[1000005];intpw[1000005];boolall[1000005];intsol[1000020];voidsolv()......