今天心情不好,不写模拟赛了
模拟赛的内容在学校写完得了,回家写小作文睡觉
模拟赛没怎么好好打。第二次打构造题,这种题和其他的是真的不一样。看来我不仅要恶补各种算法,还要锻炼一下我的思维。
T1【串】
题目大意:
给出n,k(1<=n,k<=1e5),要求构造出长度为n的01串,其中1出现k次,使得“1”出现奇数次的区间数量最多。求最多的区间个数,与构造方案
解题思路:
一眼构造->一眼不会->认认真真手算了很久,结果和上次一样从头假到尾。
根本不会,于是乎只能等题解。
————
将答案数组a[n]做前缀和,容易发现,每当1出现一次,前缀和数组sum的奇偶性就会变一次。若是要“1”要在区间(l,r)出现奇数次,那么sum[r]-sum[l-1]也是奇数。
于是乎,将前缀和数组中的奇数个数统计为x,偶数个数记为y,则有x+y=n-1,我们要使ans=xy最大,即要让x,y尽量接近,这容易算出x,y。然后,我们怎么构造呢?我们只需要使数列的前k-1位都为1、根据奇偶性在数组中放入最优的剩下的“1”就行。
点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int n,k;
int sum[N];
int x,y;
signed main()
{
cin>>n>>k;
if (k==0)
{
cout<<0;
return 0;
}
x=y=(n+1)/2;
if (n%2==0) y++;
cout<<x*y<<endl;
x--;
for (int i=1;i<=k-1;i++)
{
cout<<"1 ";
sum[i]=sum[i-1]+1;
if (sum[i]%2==0) x--;
else y--;
}
for (int i=k;i<=n;i++)
{
if (x==0||y==0)
{
cout<<"1 ";
for (int j=i+1;j<=n;j++) cout<<"0 ";
break;
}
cout<<"0 ";
sum[i]=sum[i-1];
if (sum[i]%2==0) x--;
else y--;
}
return 0;
}