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

AtCoder Beginner Contest 356 - VP记录

时间:2024-11-11 19:07:56浏览次数:3  
标签:AtCoder ch Beginner Contest int sqrt ans include 除数

A - Subsegment Reverse

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

const int N=105;
int n,a[N],l,r;

int main()
{
	scanf("%d%d%d",&n,&l,&r);
	iota(a+1,a+n+1,1);
	reverse(a+l,a+r+1);
	for(int i=1;i<=n;i++)
		printf("%d ",a[i]);
	return 0;
}

B - Nutrients

高桥出镜率 \(100 \%\)。

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

const int N=105,M=105;
int n,m,a[M],x[N][M],b[M];

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			scanf("%d",&x[i][j]);
			b[j]+=x[i][j];
		}
	bool ans=true;
	for(int i=1;i<=m;i++)
		if(b[i]<a[i])
		{
			ans=false;
			break;
		}
	printf("%s\n",ans?"Yes":"No");
	return 0;
}

C - Keys

每次必有的暴力练习题。

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

const int N=20,M=105;
int n,m,k;
int c[M],a[M][N],bt[M];
bool res[M];

int main()
{
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&c[i]);
		for(int j=1;j<=c[i];j++)
		{
			scanf("%d",&a[i][j]);
			bt[i]|=1<<(a[i][j]-1);
		}
		char str[5]; scanf("%s",str);
		res[i]=str[0]=='o';
	}
	int ans=0;
	for(int z=0;z<1<<n;z++)
	{
		bool is_ok=true;
		for(int i=1;i<=m;i++)
			if((__builtin_popcount(z&bt[i])>=k) != res[i])
			{
				is_ok=false;
				break;
			}
		if(is_ok) ans++;
	}
	printf("%d\n",ans);
	return 0;
}

D - Masked Popcount

找出 \([0,n]\) 中所有数二进制第 \(i\) 位上 \(1\) 的数量。

这是构成一个循环的,具体来说,例如 \(i=3\) 的时候,\([4,7],[12,15],[20,23],[28,31]\dots\) 的第 \(3\) 位上有 \(1\),即每 \(2^i\) 个数中有 \(2^{i-1}\) 个数第 \(i\) 位是 \(1\)。

所以我们找出循环的数量,然后剩下的一截判断是否在第 \(i\) 位上有 \(1\) 的数值区间内,若有就加上剩下的一块 \(1\)。

最后若 \(m\) 在某一位上有 \(1\),答案就要加上这一位上 \(1\) 的数量。

注意我代码里二进制最低位是第 \(0\) 位。

#include<cstdio>
using namespace std;

const int LogN=60,P=998244353;
long long n,m;
long long cnt[LogN+5];

int main()
{
	scanf("%lld%lld",&n,&m);
	long long ans=0;
	for(int i=0;i<=LogN;i++)
	{
		long long t=n;
		long long cycle=(t+1)>>(i+1);
		cnt[i]+=cycle<<i;
		t-=cycle<<(i+1);
		if(t>=1ll<<i) cnt[i]+=t-(1ll<<i)+1;
		if((m>>i)&1) ans=(ans+cnt[i])%P;
	}
	printf("%lld\n",ans);
	return 0;
}

E - Max/Min

最恶心的一道,没有之一。

将 \(a\) 从小到大排序,答案转化为:

\[\sum_{i=2}^{n} \sum_{j=1}^{i-1} \left\lfloor\frac{a_i}{a_j}\right\rfloor \]

然后将答案分为 \(a_i=a_j\) 和 \(a_i \neq a_j\) 两种情况。对于第一种情况,直接用公式即可算,难点在于第二种。

对于 \(\lfloor\frac{a_i}{a_j}\rfloor\),因为除数和商不可能都大于 \(\sqrt{a_i}\),所以将情况分为除数小于等于 \(\sqrt{a_i}\) 和被除数小于等于 \(\sqrt{a_i}\),而对于后面一种情况,为避免重复,非常不建议枚举的时候直接判断被除数(我就是这么挂十发的),而应该采用判断“除数大于 \(\sqrt{a_i}\)”的判断方式,这样才可以保证不重不漏。

  • 第一种情况:可能的商有 \(\sqrt{a_i}\) 种,当被除数、商一定时(\(\lfloor x \div y \rfloor = z\)),除数是一个确定的区间 \(\left[\lfloor\frac{x}{y+1}\rfloor+1,\lfloor\frac{x}{y}\rfloor\right]\),预处理出值域前缀和就可以直接算。

  • 第二种情况:可能的除数有 \(\sqrt{a_i}\) 种,当被除数、除数一定时,商唯一确定。直接加就行。

注意找的时候均必须找 \(a_j\) 严格小于 \(a_i\),因为等于是在刚才单独计算的。

总的来说,我这种方法代码细节超多,不是很建议学。

时间复杂度 \(O(n \sqrt{n})\)

#include<cstdio>
#include<algorithm>
#pragma GCC optimize(2)
using namespace std;

namespace IO{
template<typename TYPE> void read(TYPE &x)
{
	x=0; bool neg=false; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')neg=true;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^'0');ch=getchar();}
	if(neg) {x=-x;} return;
}
template<typename TYPE> void write(TYPE x)
{
	if(!x){putchar('0');return;} if(x<0){putchar('-');x=-x;}
	static int sta[55]; int statop=0; while(x){sta[++statop]=x%10;x/=10;}
	while(statop) {putchar('0'+sta[statop--]);} return;
}
} using namespace IO;

const int N=2e5+5,A=1e6+5;
int n,a[N],maxa;
long long ans=0;

int cnt[A];
#define qrange(l,r) (cnt[r]-cnt[(l)-1])

int main()
{
	read(n);
	for(int i=1;i<=n;i++)
	{
		read(a[i]);
		cnt[a[i]]++;
		maxa=max(maxa,a[i]);
	}
	for(int i=1;i<=maxa;i++)
	{
		if(cnt[i]) ans+=1ll*cnt[i]*(cnt[i]-1)/2;
		cnt[i]+=cnt[i-1];
	}
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++)
	{
		for(long long j=1;j*j<=a[i];j++) //枚举商
			ans+=j*qrange(a[i]/(j+1)+1,min(a[i]/j,1ll*a[i]-1));
		for(long long j=1;(a[i]/j)*(a[i]/j)>a[i];j++) //枚举除数
			ans+=(a[i]/j)*qrange(j,min(j,1ll*a[i]-1));
	}
	write(ans);
	return 0;
}

标签:AtCoder,ch,Beginner,Contest,int,sqrt,ans,include,除数
From: https://www.cnblogs.com/jerrycyx/p/18540340

相关文章

  • The 2024 ICPC Asia East Continent Online Contest (I) G
    Link:TheMedianoftheMedianoftheMedian考虑二分答案,对中位数进行二分,每次去判断是否比中位数大即可。我们钦定了一个中位数\(x\),对于\(\{a\}\)数组,若\(a_i\gex\),则令\(a_i=1\),否则\(a_i=0\),这样有一个好处,我们只关心\(1\)和\(0\)的数量,就可以知道中位数......
  • AtCoder Beginner Contest 379
    这次又是倒在了t5,没救了。ABC379A-Cyclic难度:红#include<bits/stdc++.h>usingnamespacestd;intmain(){chara,b,c;cin>>a>>b>>c;cout<<b<<c<<a<<''<<c<<a<<b;return0;}B-......
  • C - Sowing Stones(python解)-atcoder
    C-SowingStones**(python解)-atcoder原题链接:C-SowingStones问题分析:每个包含石头的单元格X[i]中有A[i]个石头。我们需要确保每个单元格从1到N最终都有1个石头。思路:可用的石头总数必须等于单元格的总数。即需要N个石头,但只有ΣA[i](其中A[i]是单元格......
  • AtCoder Beginner Contest 379
    A-Cyclic题意输入\(3\)个连续字符\(a,b,c\),输出另外两种顺序。思路模拟。代码点击查看代码#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongtypedefpair<int,int>pii;constintmxn=1e6+5;voidsolve(){ chara,b,c; cin......
  • Toyota Programming Contest 2024#11(AtCoder Beginner Contest 379)题解
    总体情况A-Cyclic题意给你一个三位整数\(N\),其中每个数字都是介于\(1\)和\(9\)之间的整数。设\(a\),\(b\),\(c\)分别是\(N\)的百位、十位和个位数。打印一个按此顺序排列\(b\),\(c\),\(a\)所组成的整数,以及一个按此顺序排列\(c\),\(a\),\(b\)所组成......
  • The 2022 ICPC Asia Hangzhou Regional Programming Contest
    Preface久违地线下训练,没想到前年的比赛还有没打过的漏网之鱼这场由于一个中期题G被看出来是去年暑假前集训做过的原,导致题目难度跨度有点大最后一共出了8题,J几何的思路其实出的大差不差了,赛后改了改就过了A.ModuloRuinstheLegend首先转化下题意,令\(A=n,B=\frac{n......
  • atcoder DP做题笔记
    [ABC163E]ActiveInfants题意:给定长度为\(n(n\le2\times10^3)\)的序列\(a\),重排使得\(a_x\times|x-p_x|\)之和最大。独立完成。从大到小地考虑\(a_i\),贪心地使得\(|x-p_x|\)最大。那么\(p_x\)要么在最左,要么在最右。因此在左边和右边形成了一坨前/后缀,然后......
  • AtCoder Beginner Contest 358 - VP记录
    Preface这次的动规题真的多,起码有三道都是。赛时做完ABCD以后就去攻G去了,可惜犯了煞笔错误搞WA了。赛后补F的时候思路代码啥的都挺顺的(没看题解独立切的蓝题),就是犯了更煞笔的错误,成消愁......
  • The 2022 ICPC Asia Hangzhou Regional Programming Contest C
    C.NoBugNoGame\(很简单的一个dp\)\(在枚举到当前为i的时候假设当前容量为j对其进行转移\)点击查看代码#include<bits/stdc++.h>#defineintlonglong#defineall(x)x.begin(),x.end()#definerall(x)x.rbegin(),x.rend()#definepbpush_back#definepiipair<......
  • The 2022 ICPC Asia Hangzhou Regional Programming Contest
    A.ModuloRuinstheLegend\(题目即求(sum+n*s+(n+1)*n/2*d)\equiv\modm的最小值\)\(由裴蜀定理可得n*s+(n+1)*n/2*d=gcd(n,(n+1)*n/2)\)\(令p=gcd(n,n*(n+1)/2)\)\(可以表示为(sum+k*p+t*m)\equiv\modm\)\(令g=gcd(p,m)\)\((sum+g*z)%m\)\(sum+g*z>=m时存在最小值\)\(......