Cap1taL @ 2022-07-25 16:05:44
用了一篇题解的思路,但最后用的是lower_bound
题解
我的代码
// 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>
#define INF 0x7fffffff
#define MAXN 200050
#define MAXM 200050
using namespace std;
int n,m;
int w[MAXN],v[MAXN];
int p[MAXN],q[MAXN];
long long sum[MAXN],num[MAXN];
long long s;
long long get(int W){
long long ans=0;
for(int i=1;i<=n;i++){
if(w[i]<W){
num[i]=num[i-1];
sum[i]=sum[i-1];
}else{
num[i]=num[i-1]+1;
sum[i]=sum[i-1]+v[i];
}
}
for(int i=1;i<=m;i++) ans+=(num[q[i]]-num[p[i]-1])*(sum[q[i]]-sum[p[i]-1]);
return ans;
}
long long fw[MAXN];
int main(){
cin>>n>>m>>s;
int maxx=-1;
for(int i=1;i<=n;i++){
scanf("%d %d",&w[i],&v[i]);
maxx=max(maxx,w[i]);
}
for(int i=1;i<=m;i++){
scanf("%d %d",&p[i],&q[i]);
}
for(int i=0;i<=maxx;i++){
fw[i]=-get(i);
}
long long *L=lower_bound(fw,fw+maxx+1,-s);
long long x=L-fw;
cout<<min(labs(s+fw[x]),labs(s+fw[x-1]));
return 0;
}
num和sum数组与题目中一样,get就是题解里的check,最后我用了fw数组记录了所有fw的值,取相反数变成上升的,最后lowerbound,在s左右两个fw里面取最小的
maxx我是记录了所有w里面最大的,这是上界,1e6试过也会TLE两个点
评测记录
复杂度最后依旧是log,为什么过不了求大佬解答QAQ
by Michvior_AC @ 2022-09-08 22:54:33
额,虽然我不是大佬,但我感觉是你把序列取反再lower_bound的问题,你把cin,cout换了是95分,把t的那一组数据下载一下你会发现,maxx是非常大的,这就导致你代码的常数贼大
by Michvior_AC @ 2022-09-09 05:45:44
复杂度可能是没有问题的,但你的常数会比正常大很多,我那个点跑了7ms, 但用你的方法需要1.14s
by Michvior_AC @ 2022-09-09 15:21:44
@XHZS_XY
by Cap1taL @ 2022-09-09 19:15:19
@Michvior_AC 明白力,远古黑历史
by Michvior_AC @ 2022-09-09 19:51:29
@XHZS_XY 好