1. 程式人生 > >聰明的質監員(二分答案,前綴和)

聰明的質監員(二分答案,前綴和)

驗證 前綴和 -m lis 2.7 不想 ret memset 包含

題目描述

小T 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有 nnn 個礦石,從 111 到 nnn 逐一編號,每個礦石都有自己的重量 wiw_iwi? 以及價值 viv_ivi? 。檢驗礦產的流程是:

1 、給定 m 個區間 [Li,Ri]

2 、選出一個參數 W

3 、對於一個區間 [Li,Ri],計算礦石在這個區間上的檢驗值 Yi

技術分享圖片

這批礦產的檢驗結果 Y 為各個區間的檢驗值之和。即: Y1+Y2...+Ym?

若這批礦產的檢驗結果與所給標準值 S 相差太多,就需要再去檢驗另一批礦產。小T不想費時間去檢驗另一批礦產,所以他想通過調整參數W 的值,讓檢驗結果盡可能的靠近標準值 S ,即使得 S−Y 的絕對值最小。請你幫忙求出這個最小值。

輸入輸出格式

輸入格式:

第一行包含三個整數 n,m,S,分別表示礦石的個數、區間的個數和標準值。

接下來的 n 行,每行 2 個整數,中間用空格隔開,第 i+1 行表示 i 號礦石的重量 wi 和價值 vi?

接下來的 m 行,表示區間,每行 2 個整數,中間用空格隔開,第 i+n+1 行表示區間 [Li,Ri]的兩個端點 LiRi 。註意:不同區間可能重合或相互重疊。

輸出格式:

一個整數,表示所求的最小值。

思路:

暴力是不行的啦,而我又不會別的qwq

所以我就想辦法開始優化

一看w才1e6,好辦,可以二分答案了。

每次二分一個答案,然後驗證

如果二分出來的答案s-y小於0,那麽可能最優解在他的右邊

反之亦然

記得每次都要更新答案喲。

怎麽驗證呢?

我們就要用到前綴和

每次二分出一個數,我就按這個條件O(N)算出前綴和

詢問的回答就可以O(1)了

代碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rii register int i
#define rij register int j
#define inf 19260817
#define int long long 
using namespace
std; long long qzhv[1000005],qzhw[1000005],s,n,m,v[200005],w[200005]; long long maxn,minx; long long z[200005],y[200005]; long long find(int wz) { long long ans=0; memset(qzhv,0,sizeof(qzhv)); memset(qzhw,0,sizeof(qzhw)); for(rii=1;i<=n;i++) { qzhv[i]=qzhv[i-1]; qzhw[i]=qzhw[i-1]; if(w[i]>=wz) { qzhw[i]++; qzhv[i]+=v[i]; } } for(rii=1;i<=m;i++) { long long ltt=z[i]; long long kkk=y[i]; ans+=(qzhw[kkk]-qzhw[ltt-1])*(qzhv[kkk]-qzhv[ltt-1]); } return ans; } long long qabs(long long val) { if(val>0) { return val; } else { return val*(-1); } } signed main() { maxn=-inf; minx=inf; scanf("%d%d%lld",&n,&m,&s); for(rii=1;i<=n;i++) { scanf("%d%d",&w[i],&v[i]); maxn=max(maxn,w[i]); minx=min(minx,w[i]); } for(rii=1;i<=m;i++) { scanf("%d%d",&z[i],&y[i]); } int l=minx-1; int r=maxn+2; minx=9999999999999999; while(l!=r) { if(r-l==1) { minx=min(minx,min(qabs(find(l)-s),qabs(find(r)-s))); break; } int mid=(l+r)/2; long long qaq=find(mid); minx=min(minx,qabs(qaq-s)); qaq=qaq-s; if(qaq<0) { r=mid; } else { l=mid; } } cout<<minx; }

聰明的質監員(二分答案,前綴和)