2025/7/14模拟赛
2025/7/14\(\mathbf{} \begin{Bmatrix} \frac{{\Large TEST} }{{\color{Yellow}\Large Record} }\mathbf{} {No.6} \end{Bmatrix}\times{}\) NeeDna
难度主观估计:\({\color{Yellow} t1} <{\color{Blue} t4} <{\color{Purple} t3} <{\color{Purple} t2}\)
题意:
构造一个长度为 \(n\) ,有 \(k\) 个 \(1\) 的01串,求包含奇数个 \(1\) 的子串个数的最大值。
反思:
在这道题没有打表,暴力也写的不够好,思路方向不正确。
题解:
假设我们已经得到了一个01串,我们该怎样计算他的贡献,我们求一个前缀和数组 \(S\)。
假设一个子串 \([l,r]\) 对答案有贡献,有一个充要条件就是 \(S_{r}-S_{l} \equiv 1 \pmod 2\)
加入我们设 \(X=\sum_{i=0}^{n}[S_{i}\equiv 0 \pmod 2],Y=\sum_{i=0}^{n}[S_{i}\equiv 1 \pmod 2]\)
根据乘法原理那么答案就是 \(X\times Y\) 了。又因为 \(X+Y=n+1\),根据基本不等式,假如要让 \(ans\) 最大,就要让 \(X,Y\) 尽量相等。
考虑一种构造满足这个条件:
-
前 \(k-1\) 个数都填 \(1\)。
-
最后一个 \(1\) 填在剩下的数中间。
code:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,k,a[100005],cnt1,cnt0,num=1,sum=0;
int main(){
cin>>n>>k;if(k==0){cout<<0<<'\n';for(int i=1;i<=n;i++) cout<<0<<' ';return 0;}
for(int i=1;i<k;i++) a[num++]=1;a[(num+n+1)/2]=1;
for(int i=1;i<=n;i++) {sum+=a[i];if(sum%2==1) cnt1++;else cnt0++;}
cout<<cnt1*(cnt0+1)<<'\n';for(int i=1;i<=n;i++) cout<<a[i]<<' ';
}
本题是CF1553I的简化版,做到 \(O(n^2)\) 即可。
给定一棵 \(n\) 个点的树, 每一个结点都可以是黑色或白色, 每一条边的长度都为 \(1\) 。
定义两个点的距离为两个点最短路径上边的条数, 定义一棵树的价值, 为同色点距离的最大值。 请求出在所有情况下, 树的价值之和, 对 \(1e9+7\) 取模。

反思:
-
首先就没给这道题留够足够的时间,只留了20min左右的思考时间。
-
题意简单但也没读明白。
-
这道题的思路从链推广到树上,做法都是一样的,但是因为上一条,所以没看出来。
-
树的直径和代码能力有待提高和更深的认知。
代码晚上写了但是没调出来,贴一份wyb的code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
const int N=1e6+10,mod=1e9+7;
vector<int> G[N];
int n,dep[N],dep1[N],mxdep,pl,rt,rt_,c[N];
ll pw[N]={1};
void dfs(int u,int fa){
if(dep[u]>mxdep) mxdep=dep[u],pl=u;
for(auto v:G[u]){
if(v==fa) continue;
dep[v]=dep[u]+1;
dfs(v,u);
}
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) pw[i]=pw[i-1]*2%mod;
for(int i=1,u,v;i<n;i++){
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1,0);
mxdep=0,dep[rt=pl]=0; dfs(rt,0);
for(int i=1;i<=n;i++) c[dep1[i]=dep[i]]++;
mxdep=0,dep[rt_=pl]=0; dfs(rt_,0);
for(int i=1;i<=n;i++) c[dep[i]]++;
int minn=0;
for(int i=1;i<=n;i++) minn=max(minn,min(dep[i],dep1[i]));
int sum=pw[n],tot=n+1,ans=0;
for(int i=mxdep;i>minn;i--){
tot-=c[i];
int nxt=pw[tot];
(ans+=1ll*i*(sum-nxt+mod)%mod)%=mod;
sum=nxt;
}
(ans+=1ll*minn*sum%mod)%=mod;
cout<<ans;
return 0;
}

浙公网安备 33010602011771号