Codeforces Round #774 (Div.2)

A. Square Counting

Description

Luis 有一个长为 (n+1) 的整数序列 a,保证 i[1,n+1]0ai<nai=n2,记 s=i=1n+1ai。现在 Luis 丢了这个序列,但是还留下 ns,求序列中有几个数的值为 n2

Solution

明显地,答案就是 sn2,也就是说,能放下几个 n2 就放下几个 n2,剩下的 smodn2 一定能够将其他数字填充进去,因为 smodn2<n2,而剩下所有数和的最大可能值为 (n1)(n+1)=n21,不用担心不够填充。

单次询问时间复杂度 O(1)

Code

记得要开 long long

#include<bits/stdc++.h> using namespace std; int main() { int T; scanf("%d",&T); while(T--) { long long n,s; scanf("%lld%lld",&n,&s); printf("%lld\n",s/(n*n)); } return 0; }

B. Quality vs Quantity

Description

有一个长为 n 的非负整数数列 a,将里面的数涂成红色 或者 蓝色。问是否有可能红色数的数量小于蓝色数的数量且红色数的总和大于蓝色数的总和。

Solution

必须的,我们要把 a 从小到大排序。每次我们枚举蓝色数的数量 i,为了使红色数的总和尽可能的大,我们令红色数的数量为 (i1),且取的就是最大的 (i1) 个数,而蓝色数取的就是最小的 i 个数,一直枚举到两种颜色有交集,只要出现红色数的总和大于蓝色数的总和即 j=ni+2naj>j=1iaj,输出 YES,若一直没有,则输出 NO

单次询问时间复杂度 O(nlogn)

Code

依然要开 long long

#include<bits/stdc++.h> using namespace std; int a[200005]; int main() { int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1); long long x=a[1]+a[2],y=a[n]; bool flag=x<y; for(int i=3;i<n-i+2;i++) { x+=a[i]; y+=a[n-i+2]; if(x<y) flag=1; if(flag) break; } if(flag) puts("YES"); else puts("NO"); } return 0; }

C. Factorials and Powers of Two

Description

定义一个数为 强大的 当其可以被写成 2dd! 的形式(dN+)。特别的,0!=1。现给出一个正整数 n,问 n 最少能够拆解为几个不同的强大的数的和。若不能拆解,输出 -1

Solution

为了方便,此处定义阶乘的反函数为 arcfac(x)

题目给出的范围为 n1012,而 log1012=39arcfac(1012)=14,其中 20=0!=1!=121=2!=2,所以在数据范围内不同的强大的数有 39+1421=50 个。如果我们全部暴力 dfs 肯定是不行的。但是发现阶乘数却只有 14 个,如果只枚举阶乘数,是可以过的。

事实上,一个自然数 x 能被 bitcount(x) 个不同的 2 的整数幂分解,其中 bitcount(x)x 的二进制表示中 1 的个数。这是显而易见的。于是我们可以枚举阶乘数,将余下的部分求 bitcount,求得每一种方案的分解数,最后去最小值即可。

单次询问时间复杂度为 O(2arcfac(n)logn)

Code

还是要开 long long

#include<bits/stdc++.h> using namespace std; long long n,fac[20]; int ans; inline int bitcount(long long x) { int tot=0; while(x) { tot+=x&1; x>>=1; } return tot; } inline void dfs(int pos,long long sum,int chosen) { if(sum+fac[pos]>n||pos==16) { ans=min(ans,chosen+bitcount(n-sum)); return; } dfs(pos+1,sum,chosen); dfs(pos+1,sum+fac[pos],chosen+1); } int main() { fac[0]=1; for(int i=1;i<=15;i++) fac[i]=fac[i-1]*i; int T; scanf("%d",&T); while(T--) { scanf("%lld",&n); ans=100; dfs(0,0,0); printf("%d\n",ans); } return 0; }

D~F 题鉴于我太菜了,就不写了,也写不出来。


__EOF__

本文作者ryanright
本文链接https://www.cnblogs.com/ryanright/p/15972410.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   ryanright  阅读(88)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示