CF CodeTON Round 1
A#
题意:
给定长度为的数组,寻找一对,使得对于所有的,满足
题解:
是最大值,是最小值。
#include<bits/stdc++.h>
using namespace std;
namespace red{
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define lowbit(i) ((i)&(-i))
#define mid ((l+r)>>1)
#define eps (1e-8)
const int N=3e5+10,mod=998244353,inf=2e9;
int n,m;
int a[N];
int maxn,p1,minn,p2;
inline void main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T;cin>>T;
while(T--)
{
cin>>n;
p1=p2=0;
maxn=-inf,minn=inf;
for(int i=1;i<=n;++i)
{
cin>>a[i];
if(a[i]>maxn) maxn=a[i],p1=i;
if(a[i]<minn) minn=a[i],p2=i;
}
cout<<p1<<' '<<p2<<'\n';
}
}
}
signed main()
{
red::main();
return 0;
}
/*
4 4
zzzz
z.z.
.zzz
zzzz
*/
B#
题意:
给个数的列表,每次可以从中删除某个数字,然后剩余的数字全部减去,次操作后能否使剩余数字恰好为?
题解:
如果我们在第一步选择删除,第二步删除,第三步删除,看看会发生什么:
删除,变为
删除原来的,变为
如此传递下去,其实最后的剩下数字的大小就是某两个数相减的结果。
看看任意两个数字的差值是否为就可以了。
#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define lowbit(i) ((i)&(-i))
#define mid ((l+r)>>1)
#define eps (1e-8)
const int N=3e5+10,mod=998244353,inf=2e9;
int n,m;
int a[N];
map<int,int> q;
inline void main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T;cin>>T;
while(T--)
{
cin>>n>>m;
q.clear();
bool flag=0;
for(int i=1;i<=n;++i)
{
cin>>a[i];
if(q[a[i]-m]==1||q[a[i]+m]==1) flag=1;
q[a[i]]=1;
}
if(flag) cout<<"YES\n";
else cout<<"NO\n";
}
}
}
signed main()
{
red::main();
return 0;
}
/*
4 4
zzzz
z.z.
.zzz
zzzz
*/
C#
题意:
给定一个长度为的非负整数数组,每次可以选择一个,让每个元素都,能否通过有限次操作让所有数字相等?
题解:
其实可以知道如果序列中有,那么所有数字都应该模成,如果序列中有,那么所有数字都应该模成
如果都有刚好凑一对就寄了。
然后如果都应该模成一定可以做到,从大到小对每个数字取模它本身就行了。
最后讨论怎么都判断能否都模成:
然后我们把数组从小到大排序,如果相邻的两个数字刚好差,就永远模不成了,因为相差为的两个数字同时取模的话,一定是一个最后为,另一个最后为。
#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define lowbit(i) ((i)&(-i))
#define mid ((l+r)>>1)
#define eps (1e-8)
const int N=3e5+10,mod=998244353,inf=2e9;
int n,m;
int a[N];
inline void main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T;cin>>T;
while(T--)
{
cin>>n;
bool flag0=0,flag1=0;
for(int i=1;i<=n;++i)
{
cin>>a[i];
if(a[i]==0) flag0=1;
if(a[i]==1) flag1=1;
}
sort(a+1,a+n+1);
if(!flag1)
{
cout<<"YES\n";
continue;
}
if(flag1&&flag0)
{
cout<<"NO\n";
continue;
}
bool flag=0;
for(int i=1;i<n;++i)
{
if(a[i]+1==a[i+1]) flag=1;
}
if(flag) cout<<"NO\n";
else cout<<"YES\n";
}
}
}
signed main()
{
red::main();
return 0;
}
/*
4 4
zzzz
z.z.
.zzz
zzzz
*/
D#
题意:
定义一个正整数是的,当且仅当可以表示为个模不同余的数字之和。
给定一个正整数,求,使得是的,或者表示不存在。
题解:
先小讨论一下特殊情况:
是奇数,直接完事。
是偶数,找规律:
首先考虑构造一组解,如果,那么皆大欢喜,但事实不会这么巧。
我们还有一个调整法,那就是给任意一项加,都是符合要求的,但是事实也不会这么巧。
我们把右边的式子收缩一下
那么给任意一项之后式子会怎么变化呢?假如加了个,那么式子变为
也就是
那么就是把拆分成两个奇偶不同的数字之积。
我们把写错
那么和中较小的那个就是,但是不能为
#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define lowbit(i) ((i)&(-i))
#define mid ((l+r)>>1)
#define eps (1e-8)
const int N=3e5+10,mod=998244353,inf=2e9;
int n,m,ans;
int top,sum;
inline int dc(int x)
{
return x*(x+1)/2;
}
inline void main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T;cin>>T;
while(T--)
{
cin>>n;
// if(n==6)
// {
// cout<<3<<'\n';
// continue;
// }
if(n%2==1)
{
cout<<2<<'\n';
continue;
}
int x=n,y=1;
while(x%2==0) x/=2,y*=2;
if(x==1)
{
cout<<"-1\n";
continue;
}
if(y*2<=x)
{
cout<<y*2<<'\n';
continue;
}
//y*2>x
cout<<x<<'\n';
}
}
}
signed main()
{
red::main();
return 0;
}
/*
5
2
4
1516512161616
89784856616161
99999999999999998
*/
E#
题意:
给定一颗无向无根树,你要为每个点安排一个权值,使得删除每个点后,所有连通块权值之和相等。
题解:
把树二分染色,深度为奇数的节点权值为负,深度为偶数的节点权值为正,权值大小等于节点的度数。
证明:
整个树的权值之和是,因为每条边给其中一个节点,另外一个节点。
删除一个点后,剩下的每个连通块权值都是或,因为每个连通块只有一条边的平衡被打破了。
#include<bits/stdc++.h>
using namespace std;
namespace red{
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define lowbit(i) ((i)&(-i))
#define mid ((l+r)>>1)
#define eps (1e-8)
const int N=3e5+10,mod=998244353,inf=2e9;
int n,m;
int a[N];
vector<int> eg[N];
int dep[N],sum[N];
inline void dfs(int now,int fa)
{
dep[now]=dep[fa]+1;
for(int t:eg[now])
{
if(t==fa) continue;
++sum[t];++sum[now];
dfs(t,now);
}
if(dep[now]%2==0) sum[now]=-sum[now];
}
inline void main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T;cin>>T;
while(T--)
{
cin>>n;
for(int i=1;i<=n;++i)
{
sum[i]=0;
eg[i].clear();
}
for(int i=1;i<n;++i)
{
int x,y;
cin>>x>>y;
eg[x].push_back(y);
eg[y].push_back(x);
}
dfs(1,0);
for(int i=1;i<=n;++i) cout<<sum[i]<<" \n"[i==n];
}
}
}
signed main()
{
red::main();
return 0;
}
/*
4 4
zzzz
z.z.
.zzz
zzzz
*/
F#
题意:
给定个节点,每个节点权值为,对于任意实数,考虑以为基础的图,任意两个节点之间的边权为,设为中的最小生成树的权值和,求的上界,或说明它无上界。
题解:
设,那么边权
从这个角度来构造最小生成树,对于每个点来说,如果,则和连边,如果则和连边。
那么就是说,只有在的时候才会让某个点的连边状态发生改变。
只要枚举在等于每个时的答案,通过一些预处理直接算偏移量。
(只是用来分析,实际求贡献不用从角度考虑,因为有,实际上从角度考虑更方便。)
#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define lowbit(i) ((i)&(-i))
#define mid ((l+r)>>1)
#define eps (1e-8)
const int N=3e5+10,mod=998244353,inf=2e9;
int n,m;
int a[N],ans;
inline void main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T;cin>>T;
while(T--)
{
cin>>n;
int tsum=0;
for(int i=1;i<=n;++i)
{
cin>>a[i];
tsum+=a[i];
}
//b[i]=a[i]+t
//b[u]*b[v]-t^2
sort(a+1,a+n+1);
if(a[n]*(n-2)+tsum<0||a[1]*(n-2)+tsum>0)
{
cout<<"INF\n";
continue;
}
int dv=0;
int val=0;
for(int i=2;i<=n;++i)
{
val+=a[1]+a[i];
dv+=a[1]*a[i];
}
ans=-inf*inf;
for(int i=2;i<=n;++i)
{
int l=-a[i],r=-a[i-1];
ans=max(ans,max(val*l+dv,val*r+dv));
val-=a[1];
val+=a[n];
dv+=a[i]*(a[n]-a[1]);
}
cout<<ans<<'\n';
}
}
}
signed main()
{
red::main();
return 0;
}
/*
4 4
zzzz
z.z.
.zzz
zzzz
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧