首页 > 其他分享 >Codeforces Round #829 A+B+C+D 题解

Codeforces Round #829 A+B+C+D 题解

时间:2022-11-18 21:35:53浏览次数:86  
标签:le10 le int 题解 Codeforces cin 829 ans

A. The Ultimate Square

题意

询问 \(T\) 次,给定 \(n\) 块木板,第 \(i\) 块为 \(1\times\lceil\frac i2\rceil\) 大小,求能拼出的最大正方形边长

数据范围: \(1\le n\le10^9,1\le T\le10^4\)

题解

\(n\) 为奇数时最大的那块木板放最上面,剩下的最大最小依次两两组合,一定能拼出 \(\lceil\frac i2\rceil\times\lceil\frac i2\rceil\) 的矩形

\(n\) 为偶数时面积最大那块不能用,剩下的就是和奇数一样

综上,答案就是 \(\lceil\frac n2\rceil\),复杂度 \(\Theta(T)\)

Code

#include<bits/stdc++.h>
using namespace std;
signed main()
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	int n,x;
	cin>>n;
	while(n--)cin>>x,cout<<(x+1)/2<<endl;
	return 0;
}

B. Diverse Substrings

题意

询问 \(T\) 次,每次给定一个长为 \(n\) 的字符串,字符串中仅包含 \(0\) 到 \(9\) 共计十种字符,询问这个字符串有多少个子序列满足其中存在的字符的重复次数都不超过其中不同的字符种类数

数据范围: \(1\le n\le10^5,1\le\sum n\le10^5,1\le T\le10^4\)

题解

乍一看似乎很恶心,实际上非常简单,注意到一共只有十种字符,也就是说每种字符都最多重复 \(10\) 次,合法子序列最大长度就是 \(100\),以每个点为起点一边枚举一边暴力判断即可,总复杂度 \(\Theta(T\times100\sum n)\)

Code

#include<bits/stdc++.h>
using namespace std;
string a;
int n,ans;
int b[15];
inline void Main()
{
	ans=0;
	cin>>n>>a;
	bool ok;
	for(int i=0,cnt;i<n;++i)
	{
		cnt=0;
		for(int i=0;i<10;++i)b[i]=0;
		for(int j=i;j<i+100&&j<n;++j)
		{
			if(++b[a[j]^48]==1)++cnt;
			ok=1;
			for(int k=0;k<10;++k)
                if(b[k]>cnt)ok=0;
			if(ok)++ans;
		}
	}
	cout<<ans<<endl;
}
signed main()
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	int T;
	cin>>T;
	while(T--)Main();
	return 0;
}

C. Zero-Sum Prefixes

题意

询问 \(T\) 次,每次给定长度为 \(n\) 的序列 \(\{a_n\}\),如果 \(a_i=0\) 你就可以把它换为任意其他数字,求操作完成后的序列最多有多少个前缀和为 \(0\),形式化地讲,你需要使得满足 \(\sum_{k=1}^ia_k\) 的 \(i\) 尽可能的多

数据范围: \(1\le n\le2\times10^5,1\le\sum n\le2\times10^5,1\le T\le10^4\)

题解

更改某个值,只会影响这个位置以及后面位置的前缀和,如果改为 \(c\),相当于给所有后面的前缀和都加上了 \(c\),由于 \(c\) 可以是任意数,所以就相当于可以把这个 \(0\) 到下一个 \(0\) 中间的所有前缀和都可以整体加上一个整数,下一个 \(0\) 可以变为任意整数就能消除这次变化的影响, 要让前缀和为 \(0\) 的最多,也就是问任意两个 \(0\) 之间的众数出现了多少次,开个桶 \(\Theta(n)\) 扫一遍就可以了,总复杂度 \(\Theta(Tn)\)

有几个细节需要注意容易写错,首先是注意统计众数个数的区间是这个零的位置到下一个零的前一个位置,别忘了要记得统计最开头到第一个零的位置的答案还有最后一个零到最后的位置的贡献,如果一个零都没有也要特判

Code

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=2e5+5;
int n,ans;
ll s[N];
vector<int>zero;
map<ll,int>m;
inline void Main()
{
	zero.clear();
	ans=0;
	cin>>n;
	for(int i=1,tmp;i<=n;++i)
	{
		cin>>tmp,s[i]=s[i-1]+tmp;
		if(tmp==0)zero.emplace_back(i);
	}
	if(zero.empty())
	{
		for(int i=1;i<=n;++i)if(s[i]==0)++ans;
		cout<<ans<<endl;
		return;
	}
	for(int i=1;i<zero.front();++i)if(s[i]==0)++ans;
	int mx;
	for(auto x=zero.begin();(*x)!=zero.back();++x)
	{
		mx=0;
		m.clear();
		for(int i=*x;i<(*(x+1));++i)
			mx=max(mx,++m[s[i]]);
		ans+=mx;
	}
	mx=0;
	m.clear();
	for(int i=zero.back();i<=n;++i)
		mx=max(mx,++m[s[i]]);
	ans+=mx;
	cout<<ans<<endl;
}
signed main()
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	int T;
	cin>>T;
	while(T--)Main();
	return 0;
}

D. ConstructOR

题意

询问 \(T\) 次,每次给定三个正整数 \(a,b,d\),请你求出在 \([0,2^{60})\) 内任意一个满足 \(a|x\) 和 \(b|x\) 都是 \(d\) 的倍数的 \(x\)( \(|\) 指按位与运算)

数据范围: \(1\le a,b,d<2^{30},1\le T\le10^4\)

题解

注意到 \(x\) 的二进制位数是 \(a,b,d\) 的两倍,有什么用呢?考虑二进制前 \(30\) 位,由于要求 \(a|x\) 和 \(b|x\) 都是 \(d\) 的倍数,这样很不好搞,所以我们就可以把前 \(30\) 位都先留出来,令 \(x=a|b\),这样 \(a|x=b|x\),但是前 \(30\) 位就被限制了,\(x\) 剩下的二进制位数正好可以留给我们进行调整使得 \(x\) 是 \(d\) 的倍数

首先如果 \(a|b\) 的最低位的 \(1\) 的位置都比 \(d\) 的最低位低,那么显然不可能将 \(d\) 乘上一个数使得更低位出现 \(1\),此时无解

然后考虑怎么构造 \(x\),可以始终保证 \(x\) 是 \(d\) 的倍数再想办法让 \(x=a|x,x=b|x\),从当前答案最低位的 \(1\) 开始向高位考虑,对于一个位置 \(k\) 如果 \(x\) 是 \(1\),而 \(a|b\) 是 \(0\),就说明我们需要再加上一个 \(d\) 的 \(2^{k-m}\) 倍( \(m\) 为 \(d\) 二进制末尾 \(0\) 的个数)来使得这一位变成 \(1\)

可能不太好理解,可以自己手玩两组样例加深理解

总复杂度 \(\Theta(30T)\) (十分不严谨的奇怪表达方式,感性理解一下)

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
int a,b,d,ans;
signed c;
inline signed lowbit(const int& x){return x&-x;}
inline void Main()
{
	cin>>a>>b>>d;
	if(min(lowbit(a),lowbit(b))<lowbit(d))return cout<<"-1\n",void(0);
	ans=0;
	for(signed i=c=__builtin_ctz(d);i<30;++i)
		if((~(ans>>i)&1)&&(((a|b)>>i)&1))
			ans+=(d<<(i-c));
	cout<<ans<<'\n';
}
signed main()
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	int T;
	cin>>T;
	while(T--)Main();
	return 0;
}	

博客园传送门

知乎传送门

标签:le10,le,int,题解,Codeforces,cin,829,ans
From: https://www.cnblogs.com/cmy-blog/p/Codeforces-833.html

相关文章

  • 【题解】做题记录(2022.11)
    11.1CF449DJzzhuandNumbers题目分析:考虑直接算的话就相当于限制每一位必须有一个\(0\),显然不如反着来,也就是某一位必须全为\(1\),也就是我们计算与之后不为\(0\)......
  • DSOJ 题解 #202103. 【21网络赛C】来帮我们排排名
    【21网络赛C】来帮我们排排名-题目-DSOJ#include<stdio.h>#include<stdlib.h>#include<string.h>structplayer_data{charid[11];intproblem_tim......
  • CodeForces - 15D Map
    题意:要在一片n*m的地上盖一个a*b的房子。这片地参差不齐,如果选定一个a*b的区域盖房子的话,需要把这片地铲地和最低点一样平,消耗的代价为铲掉高度之和。按代价大小求所有不重......
  • luogu P7201 [COCI2019-2020#1] Džumbus题解
    须知本题解骨架是本人由官方题解翻译得来的,并补充了一些不详细的地方,修改了一些错误,自己写了每一个子任务的代码(因为官方题解代码和文本不太匹配)。基本信息任务名:Džumb......
  • P5999 [CEOI2016] kangaroo 蓝 题解
    前言有些题目照常DP不是很好做,感觉像是区间DP,但是怎么设状态都不好转移,那么可以考虑一种维护块儿的DP,就是这道题要用到的知识点。背景分析如果每次跳跃的点的编号形......
  • 恒创科技:有关服务器虚拟化的常见问题解答
    虚拟化”一词经常使用,尤其是与服务器相关的时候。以下是一些有关服务器虚拟化常见问题的解答。什么是服务器虚拟化?虚拟化是一个经常应用于范围广泛的......
  • helm 问题解决 —— HELM部署异常:Error: UPGRADE FAILED: another operation (install
    转载: https://blog.csdn.net/dreamer_chen/article/details/118596034  HELM部署异常:Error:UPGRADEFAILED:anotheroperation(install/upgrade/rollback)isin......
  • week4题解
    1.深度优先搜索   思路:以固定的移动顺序走迷宫,若能到终点则记一次到终点后回溯到前一个有分岔的地方,走另一条路线若走到死路也同样回溯到前一个有分叉的地方。最......
  • DTOJ-2022-11-10-测试-题解
    题目链接ABCA这个套路已经出现了很多次了就是两条线之间的网格图路径数,做法呢就是容斥题意求满足以下条件的\(n\timesm\)的矩阵的个数对\(10^9+7\)取模对于......
  • Codeforces Round #673 (Div. 2) Problem A
    今天的题。本来打算把比赛坚持打完的,但是因为生病了,还是早点睡吧,把第一题摸了。题面如下:BTheroisapowerfulmagician.Hehasgotnpilesofcandies,thei-thpile......