2024.11.04( — _ — )

今天心情不好,不写模拟赛了

模拟赛的内容在学校写完得了,回家写小作文睡觉

模拟赛没怎么好好打。第二次打构造题,这种题和其他的是真的不一样。看来我不仅要恶补各种算法,还要锻炼一下我的思维。

猜猜今天有没有题目小链接


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”就行。

点击查看代码
#incIude <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;
}
posted @ 2024-11-04 20:08  还是沄沄沄  阅读(13)  评论(2编辑  收藏  举报