CF CodeTON Round 1

A#

题意:

给定长度为n的数组A,寻找一对1i,jn,使得对于所有的1kn,满足

|aiak|+|akaj|=|aiaj|

n2105

题解:

ai是最大值,aj是最小值。

Copy
#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#

题意:

n个数的列表,每次可以从中删除某个数字x,然后剩余的数字全部减去xn1次操作后能否使剩余数字恰好为k

2n2105,1k,ai109

题解:

如果我们在第一步选择删除x,第二步删除y,第三步删除z,看看会发生什么:

删除xy,z变为yx,zx

删除原来的yz变为zx(yx)=zy

如此传递下去,其实最后的剩下数字的大小就是某两个数相减的结果。

看看任意两个数字的差值是否为k就可以了。

Copy
#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#

题意:

给定一个长度为n的非负整数数组A,每次可以选择一个x2,让每个元素都mod x,能否通过有限次操作让所有数字相等?

x105

题解:

其实可以知道如果序列中有0,那么所有数字都应该模成0,如果序列中有1,那么所有数字都应该模成1

如果都有刚好凑一对就寄了。

然后如果都应该模成0一定可以做到,从大到小对每个数字取模它本身就行了。

最后讨论怎么都判断能否都模成1

然后我们把数组从小到大排序,如果相邻的两个数字刚好差1,就永远模不成了,因为相差为1的两个数字同时取模的话,一定是一个最后为0,另一个最后为1

Copy
#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#

题意:

定义一个正整数nkgood的,当且仅当n可以表示为k个模k不同余的数字之和。

给定一个正整数n,求k2,使得nkgood的,或者表示k不存在。

2n1018,T1015

题解:

先小讨论一下特殊情况:

n是奇数,直接2+(n2)完事。

n是偶数,找规律:

首先考虑构造一组解,如果n=1+2+3++k,那么皆大欢喜,但事实不会这么巧。

我们还有一个调整法,那就是给任意一项加k,都是符合要求的,但是事实也不会这么巧。

我们把右边的式子收缩一下1+2+3++k=(1+k)k2

那么给任意一项+k之后式子会怎么变化呢?假如加了tk,那么式子变为(1+k)k2+tk=n

也就是2n=(1+2t+k)k

那么就是把2n拆分成两个奇偶不同的数字之积。

我们把2n写错2n=2sp

那么2sp中较小的那个就是k,但是k不能为1

Copy
#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#

题意:

给定一颗无向无根树,你要为每个点安排一个权值ai,使得删除每个点后,所有连通块权值之和相等。

3n105,|ai|105ai0

题解:

把树二分染色,深度为奇数的节点权值为负,深度为偶数的节点权值为正,权值大小等于节点的度数。

证明:

整个树的权值之和是0,因为每条边给其中一个节点+1,另外一个节点1

删除一个点后,剩下的每个连通块权值都是+11,因为每个连通块只有一条边的平衡被打破了。

Copy
#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#

题意:

给定n个节点,每个节点权值为ai,对于任意实数t,考虑以t为基础的图Kn(t),任意两个节点之间的边权为wij=aiaj+t(ai+aj),设f(t)Kn(t)中的最小生成树的权值和,求f(t)的上界,或说明它无上界。

题解:

bi=ai+t,那么边权wij=bibjt2

从这个角度来构造最小生成树,对于每个点来说,如果bi>0,则和b1连边,如果bi<0则和bn连边。

那么就是说,只有在t=ai的时候才会让某个点的连边状态发生改变。

只要枚举t在等于每个ai时的答案,通过一些预处理直接算偏移量。

bi只是用来分析,实际求贡献不用从bi角度考虑,因为有t2,实际上从ai角度考虑更方便。)

Copy
#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 */
posted @   lovelyred  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示
CONTENTS