正确复杂度90分无法通过求助

P1314 [NOIP2011 提高组] 聪明的质监员

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 好


|