首页 > 其他分享 >AtCoder Beginner Contest 352 - VP记录

AtCoder Beginner Contest 352 - VP记录

时间:2024-11-19 17:10:30浏览次数:1  
标签:q1 AtCoder const Beginner Contest int pos 2e5 tail1

A - AtCoder Line

赛时整活想写异或版本的 swap 写错了还 WA 了一发。

不过现在会写了:x^=y^=x^=y

点击查看代码
#include<cstdio>
#include<algorithm>
using namespace std;

int main()
{
	int n,x,y,z;
	scanf("%d%d%d%d",&n,&x,&y,&z);
	if(x>y) swap(x,y);
	printf("%s\n",x<=z&&z<=y?"Yes":"No");
	return 0;
}

B - Typing

一眼 KMP 双指针。

点击查看代码
#include<cstdio>
#include<cstring>
using namespace std;

const int N=2e5+5;
int n,m; char s[N],t[N];

int main()
{
	scanf("%s%s",s+1,t+1);
	n=strlen(s+1),m=strlen(t+1);
	for(int i=1,j=1;j<=m;j++)
		if(s[i]==t[j])
		{
			printf("%d ",j);
			i++;
		}
	return 0;
}

C - Standing On The Shoulders

简单贪心,最后的高度为所有人的肩高加上最上面一个人的头高(身高减肩高),肩高总和无法改变,所以找出最大头高放在最顶上即可。答案为:\(\sum a_i + \max\{b_i-a_i\}\)。

点击查看代码
const int N=2e5+5;
int n,a[N],b[N];

int main()
{
	read(n);
	int extra=0;
	long long ans=0;
	for(int i=1;i<=n;i++)
	{
		read(a[i]),read(b[i]);
		ans+=a[i];
		extra=max(extra,b[i]-a[i]);
	}
	ans+=extra;
	write(ans,'\n');
	return 0;
}

D - Permutation Subsequence

先记录每一个数出现的位置 \(pos_{a_i}=i\),然后在数组 \(pos\) 中连续的部分表示的就是 \(a_i\) 值连续的数出现的位置,这其中的最大位置减最小位置就是此时的答案,即答案为:

\[\min_{i=k}^{n}\{ \max_{j=i-k+1}^{i} pos_j - \min_{j=i-k+1}^{i} pos_j \} \]

中间的最大最小值可以用线段树、ST 表等方式求,我这里用的是两个单调队列,一个存最大,一个存最小。

const int N=2e5+5;
int n,k,a[N],pos[N];
int q1[N],head1,tail1;
int q2[N],head2,tail2;

int main()
{
	read(n),read(k);
	for(int i=1;i<=n;i++)
	{
		read(a[i]);
		pos[a[i]]=i;
	}
	int ans=0x3f3f3f3f;
	for(int i=1;i<=n;i++)
	{
		if(head1<=tail1 && i-q1[head1]+1>k) q1[head1++]=0;
		while(head1<=tail1 && pos[i]>pos[q1[tail1]]) q1[tail1--]=0;
		q1[++tail1]=i;
		
		if(head2<=tail2 && i-q2[head2]+1>k) q2[head2++]=0;
		while(head2<=tail2 && pos[i]<pos[q2[tail2]]) q2[tail2--]=0;
		q2[++tail2]=i;
		
		if(i-k+1>=1) ans=min(ans,pos[q1[head1]]-pos[q2[head2]]);
	}
	write(ans,'\n');
	return 0;
}

E - Clique Connect

题目要求求取最小生成树,但是因为每次建立的是完全图,拿什么都存不下,因此肯定不能直接建图跑算法。

回想一下 Kruskal 的思想:每次选择边权最小的边,试图加入树中。而本题中每一个子图完全图中边权是一样的,所以如果要选某个子图完全图中的某一条边,那么其它所有边都需要尝试加入树中。一块完全图处理完毕后,其中所有点都应当是连通的(否则可以在不连通的两块中选一条边加入)。

因此,将所有修改按照边权 \(c\) 从小到大排序,然后从前往后将这块完全图中所有未连通的点连在一起并累加边权即为所求。

维护联通关系可以使用并查集,代码如下:

const int N=2e5+5,M=4e5+5;
int n,m;
pair<int,int> a[M];
vector<int> s[M];

int ufa[N],usz[N];
void uInit()
{
	for(int i=1;i<=n;i++)
		ufa[i]=i,usz[i]=1;
	return;
}
int uquery(int x)
{
	return ufa[x]==x?x:ufa[x]=uquery(ufa[x]);
}
inline void umerge(int x,int y)
{
	x=uquery(x),y=uquery(y);
	if(usz[x]<usz[y]) swap(x,y);
	usz[x]+=usz[y],ufa[y]=x;
	return;
}

int main()
{
	read(n),read(m);
	for(int i=1;i<=m;i++)
	{
		int k; read(k);
		read(a[i].first); a[i].second=i;
		s[i].resize(k);
		for(int j=0;j<k;j++)
			read(s[i][j]);
	}
	sort(a+1,a+m+1);
	long long ans=0;
	uInit();
	for(int i=1;i<=m;i++)
	{
		vector<int> &cur=s[a[i].second];
		for(int j=1;j<(int)cur.size();j++)
			if(uquery(cur[0])!=uquery(cur[j]))
			{
				umerge(cur[0],cur[j]);
				ans+=a[i].first;
			}
	}
	bool is_conn=true;
	int uq1=uquery(1);
	for(int i=1;i<=n;i++)
		if(uquery(i)!=uq1)
		{
			is_conn=false;
			break;
		}
	if(is_conn) write(ans,'\n');
	else puts("-1");
	return 0;
}

标签:q1,AtCoder,const,Beginner,Contest,int,pos,2e5,tail1
From: https://www.cnblogs.com/jerrycyx/p/18555114

相关文章

  • The 2024 ICPC Asia East Continent Online Contest (II) K.Match
    题面K.Match给定长度为\(n\)的两个序列\(a\)和\(b\),当且仅当\(a_i\oplusb_j\gek\)时,\(a_i\)与\(b_j\)连一条双向边,其中\(\oplus\)表示XOR运算。对于\([1,n]\)范围内的每个\(x\),计算大小为\(x\)的匹配数的个数,结果对\(998244353\)取模。题解考虑两......
  • Atcoder Beginner Contest 367
    老规矩此处略过前三题,不过B值得关注一下。D题 Pedometer思路肥肠煎蛋,只需要搞一个前缀额然后看前面的前缀和是否有跟当前的前缀和同余的情况(%M)暴力求解这步是O(n^2)的,因此需要优化。这里就用到了一个技巧——哈希表消除分支。所谓的哈希表消除分支其实就是mp[pre_s]存一......
  • 题解:CF contest 2037 : [Codeforces Round 988 (Div. 3)] (A-E)
    ATwice题面Kinich醒来迎接新的一天的开始。他打开手机,查看邮箱,发现了一份神秘的礼物。他决定打开礼物的盒子。Kinich用\(n\)整数打开数组\(a\)。最初,Kinich的分数是\(0\)。他将执行任意次数的以下操作:—选择两个索引\(i\)和\(j\)\((1\leqi\lt;j\leqn)\),确......
  • AtCoder Beginner Contest 380 (A~E)题解
    A-123233遍历字符串统计出现次数即可。#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e6+10;intn,m,k;inta[N];signedmain(){ strings; cin>>s; map<char,int>mp; for(autot:s){ mp[t]++; } if(......
  • [题解]AtCoder Beginner Contest 380(ABC380) A~F
    A-123233照题意统计即可。点击查看代码#include<bits/stdc++.h>usingnamespacestd;strings;map<char,int>ma;signedmain(){ cin>>s; for(chari:s)ma[i]++; if(ma['1']==1&&ma['2']==2&&ma['3']==3)co......
  • 【未完结】 AtCoder Beginner Contest 380 题解
    AtCoderBeginnerContest380Rated:\(770\)A-123233简单模拟B-HurdleParsing字符串模拟C-MoveSegment找到第\(k\)个块的下标,模拟。D-StrangeMirroringE-1DBucketToolF-ExchangeGameG-AnotherShuffleWindow......
  • 【AtCoder】Beginner Contest 378-E.Mod Sigma Problem
    题目链接ProblemStatementYouaregivenasequenceA=(A1......
  • 【AtCoder】Beginner Contest 378-F.Add One Edge 2
    [题目链接](F-AddOneEdge2(atcoder.jp))ProblemStatementYouaregivenatreewithNNNvertices.Thei......
  • AtCoder Beginner Contest 380 A - E
    link赛时是ABC,D一眼要找规律,跳了,E题思路想了接近半个小时,然后发现假了,最后没调出来,问一下dalao发现其实很简单维护。。。基础线段树没切掉,哎呦不过发现比赛打多了,理解速度和手速都有些提高,幸好前三题秒掉了,要不然rating又会是一坨A-123233B-HurdleParsingC-M......
  • AtCoder Beginner Contest 380
    省流版A.计数判断即可B.计数统计即可C.模拟即可D.注意到字符串是左右大小写镜像,从长度大往小依次考虑实际所处的位置,维护镜像次数集合E.并查集维护连通性,并尝试与左右俩格子合并即可F.博弈\(dp\),状态数只有\(5e5\),直接记忆化搜索即可G.枚举打乱起始位置,全排列分......