CF2218 比赛题解
注意:这里不讲过于简单的题,过于简单的题会放代码,但不会讲。
A
#include<iostream>
using namespace std;
int main(){
int t,n;
cin>>t;
while(t--){
cin>>n;
cout<<n<<endl;
}
return 0;
}
B
#include<iostream>
using namespace std;
int t,a[15],sums,ans=-1e9;
int main(){
cin>>t;
while(t--){
sums=0;
ans=-1e9;
for(int i=1;i<=7;i++){
cin>>a[i];
sums+=a[i];
}
for(int i=1;i<=7;i++){
ans=max(ans,a[i]-(sums-a[i]));
}
cout<<ans<<endl;
}
return 0;
}
C
#include<iostream>
using namespace std;
int t,n;
int main(){
cin>>t;
while(t--){
cin>>n;
for(int i=0;i<n;i++){
cout<<3*n-1-2*i<<" "<<3*n-2*i<<" "<<i+1<<" ";
}
cout<<endl;
}
return 0;
}
D
\(*\color{brown}{433}\)
考虑筛出前 \(n\) 个质数,假设它们从小到大分别是 \(p_1,\cdots,p_n\) ,那么构造 \(a_i\gets p_ip_{i+1}\) 即可。
#include<iostream>
#define int long long
using namespace std;
int t,n,a[1000005],b[1000005],r;
void shai(int n){
a[0]=a[1]=1;
for(int i=2;i<=n;i++){
if(!a[i]){
b[++r]=i;
}
for(int j=1;j<=r&&i*b[j]<=n;j++){
a[i*b[j]]=1;
if(i%b[j]==0){
break;
}
}
}
}
signed main(){
shai(1000000);
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++){
cout<<b[i]*b[i+1]<<" ";
}
cout<<endl;
}
return 0;
}
E
\(*\color{brown}{701}\)
- Observation 1:答案 \(ans=\max\limits_{1\le i<j\le n}(a_i\oplus a_j)\) 。
因此直接暴力枚举输出即可,复杂度 \(O(n^2)\) 。
#include<iostream>
using namespace std;
int t,n,a[3205],ans;
int main(){
cin>>t;
while(t--){
cin>>n;
ans=0;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
ans=max(ans,(a[i]^a[j]));
}
}
cout<<ans<<endl;
}
return 0;
}
F
\(*\color{green}{1086}\)
考虑 dp ,令 \(f_{i,j}\) 为有没有 \(i\) 个偶子树, \(j\) 个奇子树的方案, \(g_{i,j}\) 表示是否存在 \((x_1,\cdots,x_m),(y_1,\cdots,y_m)\) 满足 \(\operatorname{And}\limits_{k=1}^m (f_{x_k,y_k})=1\) 且 \((\sum\limits_{k=1}^m x_k)=i,(\sum\limits_{k=1}^m y_k)=j\) 。
这个 dp 一定是有规律的,考虑写一个打表的程序:
#include<iostream>
using namespace std;
int n,f[1005][1005],g[1005][1005];
int main(){
cin>>n;
f[0][0]=0;
g[0][0]=1;
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){//(even,odd)
if(i==0&&j==0){
cout<<g[i][j]<<" ";
continue;
}
if((i+j)%2==1){
if(j>=1){
f[i][j]=g[i][j-1];
}
else{
f[i][j]=0;
}
}
else{
if(i>=1){
f[i][j]=g[i-1][j];
}
else{
f[i][j]=0;
}
}
for(int k=0;k<=i;k++){
for(int l=0;l<=j;l++){
g[i][j]|=(g[k][l]&f[i-k][j-l]);
}
}
cout<<g[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
注意到如下性质:
- Observation 1 :\(g_{x,y}=1\) 当且仅当 \(y\ge x\) ,\(f_{x,y}=1\) 当且仅当 \(x=0\) 且 \(y\) 为奇数或 \(x\neq 0\) 且 \(y\ge x\) 。
因此可以仿照原 dp 的形式,递归处理本题。
接下来就是无聊的写代码时间了。
#include<iostream>
#include<vector>
using namespace std;
int n,m,r,t;
vector<int> G[500005];
void f(int root,int x,int y){
if(x<0||y<0){
return ;
}
if(root!=-1){
//g[i][j]|=(g[k][l]&f[i-k][j-l])
if(x==0){
for(int l=0;l<=y;l++){
if((y-l)%2==0){
continue;
}
f(root,0,l);
int nowr=r;
f(-1,x,y-l);
G[root].push_back(nowr+1);
G[nowr+1].push_back(root);
return ;
}
return ;
}
for(int l=x;l<=y;l++){
if((y-l)%2==0){
continue;
}
f(root,x,l);
int nowr=r;
f(-1,0,y-l);
G[root].push_back(nowr+1);
G[nowr+1].push_back(root);
return ;
}
//k<=l,x-k<=y-l,1<=k<x,1<=l<y
//k<=l<=y+k-x
for(int k=1;k<x;k++){
if(k>y+k-x){
continue;
}
f(root,k,k);
int nowr=r;
f(-1,x-k,y-k);
G[root].push_back(nowr+1);
G[nowr+1].push_back(root);
return ;
}
int nowr=r;
G[root].push_back(nowr+1);
G[nowr+1].push_back(root);
f(-1,x,y);
}
if(root==-1){
++r;
if((x+y)%2==0){
f(r,x-1,y);
}
else{
f(r,x,y-1);
}
}
}
void dfs(int x,int fat){
for(int i=0;i<G[x].size();i++){
int to=G[x][i];
if(to==fat){
continue;
}
cout<<x<<" "<<to<<endl;
dfs(to,x);
}
}
int main(){
cin>>t;
while(t--){
for(int i=1;i<=r;i++){
G[i].clear();
}
r=0;
cin>>n>>m;
if((n==0&&m%2==0)||(n>=1&&n>m)){
cout<<"NO"<<endl;
continue;
}
f(-1,n,m);
cout<<"YES"<<endl;
dfs(1,0);
}
return 0;
}
G
\(*\color{cyan}{1488}\)
首先我们注意到一个性质:
- Observation 1 :存在一组 \((l_1,\cdots,l_n),(r_1,\cdots,r_n)\) 满足 \(\forall i,0\le l_i,r_i<n\) ,满足答案的 \(a_i\) 均在 \([l_i,r_i]\) 这个区间内。
那么接下来暴力模拟即可,代码如下:
#include<iostream>
using namespace std;
typedef long long ll;
const ll mod=676767677;
ll t,n,m,s[200005],b[200005],ans,l[200005],r[200005];
int main(){
cin>>t;
while(t--){
cin>>n>>m;
for(ll i=1;i<=n;i++){
cin>>b[i];
s[b[i]]++;
}
for(ll i=1;i<=m;i++){
s[i]+=s[i-1];
}
for(ll i=1;i<=n;i++){
if(b[i]==0){
l[i]=0,r[i]=0;
}
else{
ll fg=1,mns=1e9;
if(i>=2&&b[i]>b[i-1]){
fg=0;
mns=min(mns,b[i-1]);
}
if(i<n&&b[i]>b[i+1]){
fg=0;
mns=min(mns,b[i+1]);
}
if(!fg){
if(mns==b[i]-1){
l[i]=1;
r[i]=s[b[i]-1];
}
else{
l[i]=s[b[i]-2]+1;
r[i]=s[b[i]-1];
}
}
else{
l[i]=1;
r[i]=0;
}
}
}
ans=1;
for(ll i=1;i<=n;i++){
if(l[i]<=r[i]){
ans=(ans*(r[i]-l[i]+1))%mod;
}
else{
ans=0;
}
}
cout<<ans<<endl;
for(ll i=0;i<=n;i++){
s[i]=l[i]=r[i]=0;
}
}
return 0;
}

浙公网安备 33010602011771号