首页 > 其他分享 >Codeforces Round 899 (Div. 2)

Codeforces Round 899 (Div. 2)

时间:2023-09-26 12:55:35浏览次数:53  
标签:结点 const int 899 ans Codeforces siz using Div

Codeforces Round 899 (Div. 2)

A. Increasing Sequence

解题思路:

从左往右一个个看,从1开始,如果当前位相同\(+2\),否则\(+1\)。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
const int mod = 1e9 + 7;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;

void solve()
{
    scanf("%d", &n);
    vector<int> a(n + 1);
    int cur = 0;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        if (cur + 1 == a[i])
        {
            cur += 2;
        }
        else
        {
            cur++;
        }
    }
    printf("%d\n", cur);
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

B. Sets and Union

解题思路:

数据范围很小,可直接暴力枚举。

由于最多有50中不同的元素,我们可以枚举删去每一种元素会导致起码要连带走多少其他种类的元素,其中带走最少的就是答案。

分别记录每一个集合中有哪些元素,同时记录每个元素存在于哪些集合中,遍历即可。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
const int mod = 1e9 + 7;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;

void solve()
{
    scanf("%d", &n);
    vector<vector<int>> v(60, vector<int>(60));
    vector<vector<int>> f(60, vector<int>(60));
    unordered_map<int, int> cnt;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &k);
        for (int j = 1; j <= k; j++)
        {
            int x;
            scanf("%d", &x);
            f[x].push_back(i);
            v[i].push_back(x);
            cnt[x]++;
        }
    }
    int ans = 0;
    int num = cnt.size();
    // cout << cnt.size() << endl;
    for (int i = 1; i <= 50; i++)
    {
        if (cnt[i] == 0)
        {
            continue;
        }
        vector<int> t(60);
        int res = 0;
        for (auto u : f[i])
        {
            for (auto j : v[u])
            {
                t[j]++;
            }
        }
        for (int j = 1; j <= 50; j++)
        {
            if (t[j] && t[j] == cnt[j])
            {
                res++;
            }
        }
        // cout << i << ' ' << res << endl;
        ans = max(ans, num - res);
    }
    printf("%d\n", ans);
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

C. Card Game

解题思路:

不难发现,如果我们要取了第\(i\)位,那么第\(i\)位往后的所有正数一定都能取到。

对于奇数位的正数,如果我们取了,那么后面的偶数位的正数全部都变到奇数位上,从后往前取即可。

如果从第\(i\)位往后的第一个正数是奇数位,那么我们先将第\(i\)位往后的正数全取了,再取\(a_i\)即可。

如果从第\(i\)位往后的第一个正数是偶数位,那么我们先将\(a_i\)取了,第一个正数就是奇数位了,按上述方法即可将后面的正数取完。

所以,我们从后往前枚举选取\(a_i\),然后取\(min(suffix_i)\)即可。

答案下界为0.

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
const int mod = 1e9 + 7;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;

void solve()
{
    scanf("%d", &n);
    vector<ll> a(n + 1);
    for (int i = 1; i <= n; i++)
    {
        scanf("%lld", &a[i]);
    }
    ll ans = 0;
    ll s = 0;
    for (int i = n; i; i--)
    {
        if (i & 1)
        {
            ans = max(ans, s + a[i]);
        }
        else
        {
            ans = max(ans, s);
        }
        s += max(0ll, a[i]);
    }
    printf("%lld\n", ans);
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

D. Tree XOR

解题思路:

求解每一个结点作为根节点,或者求解选一个结点作为根节点的最优情况,一般来说换根DP.

\(siz[u]:以结点u为根的子树的结点个数\)。

\(ans[u]:以u结点为根节点的子树上,所有结点权值变为相同数,所需要的花费值\)。

使得父节点\(u\)和子节点\(v\)权值相同的花费为\(siz[v] * (a[u] \oplus a[v])\),我们递归操作即可。

\(siz[u] = \sum siz[v] + 1,其中v是u的子节点\)。

\(ans[u] = \sum ans[v] + (a[u] \oplus a[v]) * siz[v]\)。

第一次算出以\(结点1\)为根节点时,所有结点的\(siz[i]和ans[i]\)。第一次\(dfs\)完后,\(ans[1]就是答案m_1\)。

接下来我们考虑以其他节点为根应当如何计算。

从结点1出发,父节点一定会比子节点先更新到答案。

\[\begin{align*} ans[u] &= (n - siz[u]) * (a[u] \oplus a[p])\\ ans[u] &= ans[u] + (ans[p] - siz[u] * (a[u] \oplus a[p])) \end{align*} \]

代码:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

void solve()
{
	int n;
	scanf("%d",&n);
	vector<int> a(n + 1);
	for(int i = 1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	vector<vector<int>> adj(n + 1);
	for(int i = 1;i<n;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	vector<ll> ans(n + 1);
	vector<int> siz(n + 1);
	auto dfs1 = [&](auto self,int u,int p) -> void
	{
		siz[u] = 1;
		for(auto v : adj[u])
		{
			if(v == p)
			{
				continue;
			}
			self(self,v,u);
			siz[u] += siz[v];
			ans[u] += 1ll * siz[v] * (a[u] ^ a[v]) + ans[v];
		}
	};
	dfs1(dfs1,1,-1);
//	cout<<ans[1]<<endl;
	auto dfs2 = [&](auto self,int u,int p) -> void
	{
		if(u != 1)
		{
			ans[u] = 1ll * (n - siz[u]) * (a[u] ^ a[p]);
			ans[u] += 1ll * ans[p] - (1ll * siz[u] * (a[u] ^ a[p]));
		}
		for(auto v : adj[u])
		{
			if(v == p)
			{
				continue;
			}
			self(self,v,u);
		}
	};
	dfs2(dfs2,1,-1);
	for(int i = 1;i<=n;i++)
	{
		printf("%lld ",ans[i]);
	}
	puts("");
}

int main()
{
	int t = 1;
	scanf("%d",&t);
	while(t--)
	{
		solve();
	}
}

标签:结点,const,int,899,ans,Codeforces,siz,using,Div
From: https://www.cnblogs.com/value0/p/17729844.html

相关文章

  • Educational Codeforces Round 155 D (CF1879_D)
    题目大意给一个长度为\(n\)的数组,求\(\Sigma_{i=1}^{n}\Sigma_{j=i}^{n}区间异或和\times(j-i+1)\)其中\(n\leq3e5,~a[i]\leq1e9\)分析首先注意到由\(l\)到\(r\)的区间异或和可以转化为\(sum_{l-1}~XOR~sum_r\)因此,对于每一个点\(x\),无论它作为上述的\(sum......
  • Educational Codeforces Round 155 (Rated for Div. 2)
    EducationalCodeforcesRound155(RatedforDiv.2)A.Rigged!解题思路:若存在\(s[i]>=s[1]\)并且\(e[i]>=e[i]\),那么答案为\(-1\).否则,答案为\(s[1]\).代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;constintN=1e6+10;con......
  • 短视频app源码,自动滚动条挡住 div内容
    短视频app源码,自动滚动条挡住div内容<!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><html><head><metahttp-equiv="Content-Type"content="text/html;charset=utf......
  • Codeforces463-E.Team Work-组合数、DP
    Codeforces463-E.TeamWork题意:求\[\sum_{i=1}^n\binom{n}{i}i^k\]其中\(1\leqn\leq10^9\),\(1\leqk\leq5000\)。题解:其实这个题\(k\)的数据范围就已经暗示了做法的复杂度——应该是要去考虑根据\(k\)去递推了。首先为了方便,\(i=0\)这一项完全可以补上,用类似生成函......
  • Educational Codeforces Round 155 (Rated for Div. 2)
    比赛链接A.Rigged!题目链接就是一个比较简单的模拟就可以解决,如何判断能不能第一只需要考虑比他力量大的耐力是不是也比他大就行,而只要比他大,他就不可能第一,否则输出他的力量作为标杆就行,这样也可以避免比他力量小的也可以举起来。#include<bits/stdc++.h>usingnamespaces......
  • 她是 Codeforces 第四名,也是知名视频平台bilibili的“网红”
    在2023年9月24日~9月25日举办的EducationalCodeforcesRound155(RatedforDiv.2)上,以优秀成绩拿下第四名仅学了ACM一年的Nanani,成为最夺目的选手之一。而且虽然是仅学了一年的选手,但她取得优异成绩后,不少网友并不感到陌生,纷纷留言:这不是bilibili上天天直播爆切神仙题的妹子......
  • 解决 undefined function bcdiv()问题
    在Deepin中php7.2遇到问题:UncaughtError:Calltoundefinedfunctionbcdiv()1bcdiv函数的作用(点我查看)原因是因为缺少了PHP的bcmath扩展,导致电脑无法识别该函数。解决办法:1、查看当前php版本PHP-v12、更新源Centos下:sudoyumupdate1Ubuntu或Deepin下:sudoapt-get......
  • CodeForces 1062F Upgrading Cities
    洛谷传送门CF传送门考虑一个子问题:求从某个点\(u\)能到达的点数。如果要精确地计算出来,最优解法只能是\(O(\frac{n^2}{w})\)的bitset。但是我们还没有利用到题目的性质,我们只需要判断一个点是否至多有一个点互不可达。考虑拓扑排序的过程,队列里面的点两两互不可达。维护......
  • Codeforces 1868D. Flower-like Pseudotree
    题目链接:D-Flower-likePseudotree题目大意:给定度数数组\({d_n}\),要求构造一个\(n\)个点\(n\)条边的连通图(也就是基环树),允许有重边,但不能有自环。需要满足第\(i\)个点的度数恰好为\(d_i\),并且将环上的边全部删去后,剩下的每棵树的高度(以原先在环上的点为根)相同。首先考......
  • CodeForces 1149D Abandoning Roads
    洛谷传送门CF传送门考虑一条\(1\toi\)的路径是否在最小生成树上。称边权为\(a\)的边为轻边,边权为\(b\)的边为重边。轻边若不成环则一定在最小生成树上,因此先把轻边合并,这样形成了若干连通块。那么如果两点在一个连通块,它们只能通过轻边互达。同时,因为是树上路径,所......