题解 [UOJ #177] 新年的腮雷

传送门

  • 在 c++20 中传入 STL 的比较因子记得写成 struct cmp{inline bool operator () (...) const {}};,需要加这个 const 否则可能 CE

发现完全不可贪心,也不太能 DP
所以考虑二分答案转化为判定
然而判定性 DP 也不太能写
所以考虑化为拆分
于是问题变为将一个 \(mid\) 按逆过程拆分成 \(n\) 个数 \(\{c_1,\cdots,c_n\}\),问是否能让 \(\forall i, c_i\geqslant a_i\)
于是因为 \(b\) 数组是相同的所以每次肯定拆最大能拆的
令当前拆出来的可重集为 \(s\),剩的 \(a\) 组成集合 \(t\)
如果当前最大的 \(t<\max\{s_i\}-b_1\),就把这个 \(t\) 和一个能匹配的最小的 \(s_i\) 匹配了就好了
复杂度 \(O(n\log^2n)\)

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
//#define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n, m;
multiset<ll> s, t;
ll a[N], b[N], lim;

bool check(ll mid) {
	// cout<<"check: "<<mid<<endl;
	s.clear(); t.clear(); s.insert(mid);
	for (int i=1; i<=n; ++i) t.insert(a[i]);
	while (s.size()&&t.size()&&s.size()!=t.size()) {
		// cout<<"s: "; for (auto it:s) cout<<it<<' '; cout<<endl;
		// cout<<"t: "; for (auto it:t) cout<<it<<' '; cout<<endl;
		auto it1=*s.rbegin(), it2=*t.rbegin();
		if (it1-b[1]>=it2) {
			s.erase(s.find(it1));
			for (int j=1; j<=m; ++j) s.insert(it1-b[j]);
		}
		else {
			auto it=s.lower_bound(it2);
			if (it==s.end()) return 0;
			else s.erase(it);
			t.erase(t.find(it2));
		}
	}
	if (s.size()!=t.size()) return 0;
	for (auto it1=s.begin(),it2=t.begin(); it1!=s.end(); ++it1,++it2)
		if (*it1<*it2) return 0;
	return 1;
}

signed main()
{
	n=read(); m=read();
	for (int i=1; i<=n; ++i) lim=max(lim, a[i]=read());
	for (int i=1; i<=m; ++i) b[i]=read();
	sort(b+1, b+m+1);
	// cout<<"b: "; for (int i=1; i<=m; ++i) cout<<b[i]<<' '; cout<<endl;
	ll l=1, r=lim+(n-1)/(m-1)*b[m], mid;
	while (l<=r) {
		mid=(l+r)>>1;
		if (check(mid)) r=mid-1;
		else l=mid+1;
	}
	printf("%lld\n", r+1);

	return 0;
}
posted @ 2022-06-28 16:41  Administrator-09  阅读(1)  评论(0编辑  收藏  举报