CF-GYM-[2019 USP Try-outs] 部分题解

CF-GYM-[2019 USP Try-outs] 部分题解

C - Crystal Matryoshkas

思路:

贪心策略:

首先使用\(multiset<int>\),这个优秀的容器来储存当前剩余的套娃重量。

假设当前要包含的套娃重量为\(\mathit X\),那么:

如果存在比当前套碗重量轻的套娃,选择重量最小的那个套娃,假设重量为\(sum\),然后用容器一直查找第一个大于等于\(sum\)的套娃,然后迭代,直至不能再添加套娃,且总重量小于等于\(\mathit X\)

然后将总重量加上\(\mathit X\),同样上述的迭代方法直至没有重量更大的套娃。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <unordered_map>
// #include <bits/stdc++.h>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define chu(x)  if(DEBUG_Switch) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
#define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define du2(a,b) scanf("%d %d",&(a),&(b))
#define du1(a) scanf("%d",&(a));
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) { if (a == 0ll) {return 0ll;} a %= MOD; ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
ll poww(ll a, ll b) { if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a ;} a = a * a ; b >>= 1;} return ans;}
void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
inline long long readll() {long long tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
void pvarr_int(int *arr, int n, int strat = 1) {if (strat == 0) {n--;} repd(i, strat, n) {printf("%d%c", arr[i], i == n ? '\n' : ' ');}}
void pvarr_LL(ll *arr, int n, int strat = 1) {if (strat == 0) {n--;} repd(i, strat, n) {printf("%lld%c", arr[i], i == n ? '\n' : ' ');}}
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
#define DEBUG_Switch 0
int n, q;
multiset<int> st;
map<int, int> m;
int main()
{
#if DEBUG_Switch
	freopen("C:\\code\\input.txt", "r", stdin);
#endif
	//freopen("C:\\code\\output.txt","r",stdin);
	n = readint();
	q = readint();
	repd(i, 1, n)
	{
		int x = readint();
		m[i] = x;
		st.insert(x);
	}
	char op;
	int id, x;
	std::vector<int> v;
	int cnt = 0;
	while (q--)
	{
		scanf("%c", &op);
		if (op == '?')
		{
			cnt++;
			if (cnt == 6)
			{
				cnt = 6;
			}
			id = readint();
			ll cal = m[id];
			st.erase(st.lower_bound(cal));
			v.pb(cal);
			int ans = 1;
			int flag = 0;
			ll now;
			if (st.size())
			{
				now = *(st.begin());
				if (now <= cal)
				{
					flag = 1;
					v.pb(now);
					st.erase(st.begin());
					ans++;
				}
			}
			while (st.size())
			{
				auto it = st.lower_bound(now);
				if(it==st.end())
                    break;
				ll y = *it;
				if (now + y <= cal)
				{
					now += y;
					ans++;
				} else
				{
					break;
				}
			}
			if (flag)
			{
				now += cal;
			} else {
				now = cal;
			}
			while (1)
			{
				auto it = st.lower_bound(now);
				if (it != st.end())
				{
					ans++;
					now += (*it);
				} else
				{
					break;
				}
			}
			printf("%d\n", ans );
			for (auto &Y : v)
			{
				st.insert(Y);
			}
			v.clear();
		} else if (op == '+')
		{
			x = readint();
			id = readint();
			m[id] = x;
			st.insert(x);
		} else
		{
			id = readint();
			x = m[id];
			st.erase(st.lower_bound(x));
		}
	}
	return 0;
}



G - Hunting leshys

题目有一个很重要的限制:

Once a leshy has a superior, it can't change. In other words, each leshy appears as inferior to other leshy only once.

即在关系网中,每一个节点最多只有一个直接的父节点。

那么每一个有关系的家族中一定是一个单向链结构,而唯一可能使当前单向链结构中的节点的答案更新的方式是给当前最终祖先加一个父节点,那么我们可以用并查集来维护\(far_i\)每一个节点\(\mathit i\)当前指向的当前最终祖先,在寻找祖先的函数中对数组\(far_i\)进行路径压缩,同时用当前结构中的父节点来更新该节点的答案值即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <unordered_map>
// #include <bits/stdc++.h>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define chu(x)  if(DEBUG_Switch) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
#define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define du2(a,b) scanf("%d %d",&(a),&(b))
#define du1(a) scanf("%d",&(a));
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) { if (a == 0ll) {return 0ll;} a %= MOD; ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
ll poww(ll a, ll b) { if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a ;} a = a * a ; b >>= 1;} return ans;}
void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
inline long long readll() {long long tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
void pvarr_int(int *arr, int n, int strat = 1) {if (strat == 0) {n--;} repd(i, strat, n) {printf("%d%c", arr[i], i == n ? '\n' : ' ');}}
void pvarr_LL(ll *arr, int n, int strat = 1) {if (strat == 0) {n--;} repd(i, strat, n) {printf("%lld%c", arr[i], i == n ? '\n' : ' ');}}
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
#define DEBUG_Switch 0
int far[maxn];
int a[maxn];
void dsu_init(int n)
{
    repd(i, 0, n)
    {
        far[i] = i;
    }
}
int findpar(int x)
{
    if (x == far[x])
    {
        return x;
    } else
    {
        int res = findpar(far[x]);
        a[x] = min(a[x], a[far[x]]);
        far[x] = res;
        return res;
    }
}
int n;
int main()
{
#if DEBUG_Switch
    freopen("C:\\code\\input.txt", "r", stdin);
#endif
    //freopen("C:\\code\\output.txt","r",stdin);
    n = readint();
    int m = readint();
    repd(i, 1, n)
    {
        a[i] = readint();
    }
    dsu_init(n);
    char op;
    while (m--)
    {
        scanf("%c", &op);
        if (op == '+')
        {
            int fa = readint();
            int son = readint();
            far[son] = fa;
        } else
        {
            int x = readint();
            findpar(x);
            printf("%d\n", a[x] );
        }
    }
    return 0;
}



猜你喜欢

转载自www.cnblogs.com/qieqiemin/p/12920348.html