开始用二分,调了很久发现函数有极小值,尝试第一次写三分,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了