【Codeforces】Codeforces Round #680 Div2
https://codeforces.com/contest/1445
赛时结果
A. Array Rearrangment
一手纯模拟,没有细节问题。
#include<bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
using namespace std;
const int N=59;
inline int read() {
register int x=0, f=1; register char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-48,c=getchar();}
return x*f;
}
int T,n,x,a[N],b[N];
signed main() {
T=read();
while(T--) {
n=read(), x=read();
rep(i,1,n) a[i]=read();
rep(i,1,n) b[i]=read();
sort(a+1,a+n+1);
sort(b+1,b+n+1); reverse(b+1,b+n+1);
bool ans=1;
rep(i,1,n) if(a[i]+b[i]>x) ans=0;
if(ans==1) puts("YES");
else puts("NO");
}
return 0;
}
B. Elimination
我比较想吐槽的一道题。纯粹阅读+结论,没什么特别大的意思。答案就是 \(max(a+b,c+d)\)。
C. Division
相比于 B 和 D,C 就有意思多了。考虑将 \(q\) 质因数分解。然后由于 \(q\) 不能是 \(x\) 的约数,于是我们需要选择一个 \(q\) 的质因数,然后将 \(p\) 一直除以这个质因数直到 \(p\bmod q\neq 0\)。
#include<bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
using namespace std;
const int N=59;
inline int read() {
register int x=0, f=1; register char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-48,c=getchar();}
return x*f;
}
int T,p,q;
signed main() {
T=read();
while(T--) {
p=read(), q=read();
if(p<q) printf("%lld\n",p);
else if(p%q!=0) printf("%lld\n",p);
else {
int ans=1;
for(int i=2;i*i<=q;i++) {
if(q%i==0) {
int t=p;
while(t%q==0) t/=i;
ans=max(ans,t);
while(q%i==0) q/=i;
}
}
if(q!=1) {
while(p%q==0) p/=q;
ans=max(ans,p);
}
printf("%lld\n",ans);
}
}
return 0;
}
D. D. Divide and Sum
又是一道结论题。对于数列 \(a\),\(f(p,q)\) 永远是相等的。于是用一个组合数加上稍微模拟一下即可。
#include<bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
using namespace std;
const int N=300009, mod=998244353;
inline int read() {
register int x=0, f=1; register char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-48,c=getchar();}
return x*f;
}
int n,a[N];
int mn,fac[N], inv[N], ifac[N];
void pre() {
inv[0]=inv[1]=fac[0]=ifac[0]=1;
for(int i=1;i<=mn;i++) fac[i]=fac[i-1]*i%mod;
for(int i=2;i<=mn;i++) inv[i]=inv[mod%i]*(mod-mod/i)%mod;
for(int i=1;i<=mn;i++) ifac[i]=ifac[i-1]*inv[i]%mod;
}
int C(int x,int y) {
if(x<0||y<0||x<y) return 0;
else return fac[x]*ifac[y]%mod*ifac[x-y]%mod;
}
signed main() {
n=read();
rep(i,1,2*n) a[i]=read();
sort(a+1,a+2*n+1);
int ans=0;
rep(i,1,n) (ans+=abs(a[2*n-i+1]-a[i]))%=mod;
mn=2*n;
pre();
ans=ans*C(2*n,n)%mod;
printf("%lld\n",ans);
return 0;
}
E. Team-Building
感觉 D 和 E 的 difficulty gap 比较大。一道有意思的图论题。做法比较烦。
首先对于每一个学术小组,我们都检查一下是不是二分图,如果不是那么就不可能被选做参与活动的组。
我们设 \(c_i\) 代表 \(i\) 所属于的学术小组,\(f(i)\) 表示 \(i\) 在哪个连通块。于是对于两个学术小组,要判断两个是否是二分图,只需要连两个学术小组的连通块即可。那么时间还是 \(O(n^2)\) 的嘛?显然不是,因为最多有 \(O(m)\) 对学术小组是有边的。所以其实是 \(O(m)\)。
代码太烦了,以后回来再看看吧。
扔两个题解 https://www.cnblogs.com/George1123/p/13912680.html https://www.luogu.com.cn/blog/SSerxhs/solution-cf1444c