三分求调(希望大佬们帮帮忙)
查看原帖
三分求调(希望大佬们帮帮忙)
1229738
CyansQwQ楼主2024/6/5 12:22

开始用二分,调了很久发现函数有极小值,尝试第一次写三分,tle了,求助大佬

// Problem: P1314 [NOIP2011 提高组] 聪明的质监员
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1314
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int Max=0,Min=0x3f3f3f3f;
void solve()
{
	int n,m;
	ll s;
	cin>>n>>m>>s;
	vector<int>w(n+1),v(n+1);
	for(int i=1;i<=n;i++)
	{
		cin>>w[i]>>v[i];
		Max=max(Max,w[i]),Min=min(Min,v[i]);
	}
	vector<int>left(m+1),right(m+1);
	for(int i=1;i<=m;i++)
	    cin>>left[i]>>right[i];
	int l=Min-1,r=Max+1;
	map<int,ll>ansl,ansr;
	auto check=[&](auto check,int ml,int mr)
	{
		vector<ll>slw(n+1),slv(n+1),srw(n+1),srv(n+1);
		for(int i=1;i<=n;i++)
		{
			if(w[i]>=ml)
			  {slw[i]=slw[i-1]+1;  slv[i]=slv[i-1]+v[i];  }
			else
			  {slw[i]=slw[i-1];  slv[i]=slv[i-1]; }
			if(w[i]>=mr)
			  {srw[i]=srw[i-1]+1;  srv[i]=srv[i-1]+v[i];  }
			else
			  {srw[i]=srw[i-1];  srv[i]=srv[i-1]; }
		}
		ll x=0,y=0;
		for(int i=1;i<=m;i++)
		{
			x+=(slw[right[i]]-slw[left[i]-1])*(slv[right[i]]-slv[left[i]-1]);
			y+=(srw[right[i]]-srw[left[i]-1])*(srv[right[i]]-srv[left[i]-1]);
		}
		x=abs(x-s),y=abs(y-s);
		ansl[ml]=x,ansr[mr]=y;
		if(x>y)return true;
		else return false;
		
	};
	while(l+1<r)
	{
		int ml=l+(r-l)/3,mr=r-(r-l)/3;
		if(check(check,ml,mr)) l=ml;
		else  r=mr;
	}	
	cout<<ansl[l];
	
}
int main()
{
	ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
	solve();return 0;
}

问题大概率在三分循环那一块,循环的条件是从董晓算法的二分板子改过来的,也在博客上看到了差不多的循环体,但就是tle了

2024/6/5 12:22
加载中...