首页 > 其他分享 >教主的别墅

教主的别墅

时间:2023-12-28 15:23:03浏览次数:22  
标签:pre 别墅 最小 教主 define 我们 字典

题目大意

教主有一栋别墅,所以他雇了 \(N\) 个清洁工,有男有女。

别墅一共有 \(M\) 个房间,现在所有的清洁工在教主面前排成了一排。教主想把这 \(N\) 个清洁工分成 \(M\) 个部分。每个部分在队列中是连续的一段,让后让这 \(M\) 个部分的清洁工分别去打扫这 \(M\) 个房间。

现在教主希望每个部分的清洁工男女个数之差的最大值最小,还想知道分成的这 \(M\) 个部分分别有多少人。

教主知道可能有很多种方案可以满足男女个数之差的最大值最小,所以他想让你输出字典序最小和最大两种情况的方案。

输入

第一行两个正整数 \(N\) 与 \(M\),用空格分隔。

第二行包含一个长度为 \(N\) 的串,仅由 \(01\) 构成。如果第 \(i\) 个位置为 \(0\) 那么表示当前位置是女生。

输出

两行,每行 \(M\) 个正整数,正整数之间用空格隔开。这 \(M\) 个正整数分别表示你的方案中每个组的人数。

样例

样例输入1

8 3
11001100

样例输出1

1 2 5
5 2 1

提示

对于 \(100\%\) 的数据,有 \(N\le 5000000\),\(M\le N\) 且 \(M\le 100000\)。

思路

首先这道题字典序最大就相当于是字符串倒过来的字典序最小。

所以我们把问题转化成了给一个字符串,我们要去求字典序最小的方案。

我们可以去求一个前缀和,如果是男生我们就加一,如果是女生就减一。

而我们发现这个前缀和数组中我们最特殊的数就是 \(0\)。因为如果出现了一个 \(0\) 就代表着前面的男生数量和女生数量一样了。

现在我们就可以算出来男生与女生总数量差。

如果总数量差为 \(0\),我们看如果当前前缀和数组中 \(0\) 的个数大于等于 \(M\) 那么我们的人数差的最大值最小就是 \(0\)(可以理解为我看能不能把整个串分成 \(M\) 个差为 \(0\) 的串,而前缀和中 \(0\) 就代表前若干个人中男生和女生的个数相同)。

如果总数量差不是 \(0\),那我们要使差的最大值最小就得让这 \(M\) 段的差尽量平均,所以我们就要把这个总数量差去平均分成 \(M\) 份。

那我们现在算出来这个男生数量和女生数量的差的最小值了,我们考虑下一个问题:字典序最小。

字典序最小我们就可以去贪心的去选,看从上一次选完之后的下一个人开始的前若干个人能不能选,如果能选了,我们就选,因为这样我们就可以使前面这些组的人数尽量小(两个串字典序的比较方式是从第一个开始,找到第一个不同的位置,看哪边的小,哪边的字典序就小)。

我们在考虑下一个问题,怎么看从上一次选完之后的下一个人开始的前若干个人能不能选呢?

这里我们分两类看:

  1. 如果我们这里已经分完 \(M-1\) 段了,那么我们就把最后剩下的那些人算成一段就可以了。

  2. 如果我们没分完 \(M-1\) 段,那么我们看总男女数量差和前面的男女数量差是否小于等于我们上面算出来的最小值乘上后面还没分的段的个数(这里就相当于我看后边那些段所能接受的差是否能接受我在这里断掉所得的差)。

代码

#include <bits/stdc++.h>
#define db double
#define ll long long
#define ex exit(0)
#define endl "\n"
#define inl inline
#define null NULL
#define pll pair<ll,ll>
#define mkp(a,b) make_pair(a,b)
using namespace std;
ll pre[5000005];
ll ans[5000005];
ll n, m;
void solve(string s) {
	ll cnt0 = 0, cnt = 0, shang = 0;
	memset(pre, 0, sizeof(pre));
	for (int i = 1; i <= n; i++) {
		pre[i] = pre[i - 1];
		if (s[i] == '1') {
			pre[i]++;
		} else {
			pre[i]--;
		}
		if (!pre[i]) {
			cnt0++;
		}
	}
	ll pj;
	if (!pre[n] && cnt0 >= m) {
		pj = 0;
	} else {
		pj = abs(abs(pre[n]) - 1) / m + 1;
	}
	for (int i = 1; i <= n; i++) {
		if (cnt >= m - 1) {
			ans[++cnt] = n - i + 1;
			return ;
		}
		if (abs(pre[n] - pre[i]) <= pj * (m - cnt - 1)) {
			ans[++cnt] = i - shang;
			shang = i;
		}
	}
}
int main() {
//	freopen("villa.in", "r", stdin);
//	freopen("villa.out", "w", stdout);
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> n >> m;
	string s, t;
	cin >> s;
	t = s;
	s = " " + s;
	solve(s);
	for (int i = 1; i <= m; i++) {
		cout << ans[i] << " ";
	}
	reverse(t.begin(), t.end());
	t = " " + t;
	solve(t);
	cout << endl;
	for (int i = m; i >= 1; i--) {
		cout << ans[i] << " ";
	}
	return 0;
}

标签:pre,别墅,最小,教主,define,我们,字典
From: https://www.cnblogs.com/kklxy/p/17932785.html

相关文章

  • P2801 教主的魔法
    includeincludeincludeusingnamespacestd;constintN=1000010;intn,m;inta[N],b[N];intL[N],R[N],pos[N];intadd[N];voidmodify(intl,intr,intx){intp=pos[l],q=pos[r];if(p==q){for(inti=l;i<=r;i++)a[i]+=x;for(inti......
  • P2801 教主的魔法 题解
    一、题目描述:给你一个长度为$n$的序列$a$,你需要进行$m$次操作。$类型\1\:将区间\l\到\r\的数加\x\。$$类型\2\:求区间\l\到\r\中有多少个数大于等于\x\。$数据范围:$1\len\le1\times10^6,m\le3\times10^3$ 二、解题思路:......
  • P2801 教主的魔法
    点击查看代码#include<bits/stdc++.h>#definels(k<<1)#definers(k<<1|1)#definemid(l+r>>1)#defineintlonglongusingnamespacestd;intn,m;charopt;constintN=1e6+7;ints[N<<2],a[N],lazy[N<<2];intmaxx[N<<2......
  • 题解(教主的魔法)P2801
    题目教主的魔法题目描述教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是$N$个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为$1,2,\ldots,N$。每个人的身高一开始都是不超过$1000$的正整数。教主的魔法每次可以把闭区......
  • Luogu P2801 教主的魔法(Loj 数列分块入门 2)
    教主的魔法题目描述教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是\(N\)个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为\(1,2,\ldots,N\)。每个人的身高一开始都是不超过\(1000\)的正整数。教主的魔法每次可以把闭......
  • 10大科技公司创始人超级豪宅:由普通别墅到夏威夷小岛
    在迈克尔杰克逊遗产拍卖的时候网上曾经流传过国外房产价格对比,看到之后网友甚至感叹迈克杰克逊的房子在国内只能换一个厕所,不过国外的房价不一定都这么便宜,至少对以下这几位来说,几百万美金的房子,小Case啦。MarissaMayer职位:YahooCEO梅姐这栋位于美国PaloAlto的看起来很普通......
  • 【codevs3410】别墅房间
    problemsolutioncodes#include<iostream>#include<queue>usingnamespacestd;structxyz{intx,y;xyz(intx=0,inty=0):x(x),y(y){};};intn,m,ans;char......
  • 地编教程:如何在UE中制作一个荒废的别墅场景?
    大家好,今天给大家带来一篇地编教程,通过MattLamb的教程学习制作阴沉的维多利亚风格的别墅场景。MattLamb发布了一个维多利亚风格的废弃豪宅的模块化场景(https://www.art......