聰明的質監員(字首和,二分)
阿新 • • 發佈:2021-02-19
技術標籤:演算法二分字首和&&差分演算法動態規劃數學建模
聰明的質監員
題目連結
小 T 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有 n 個礦石,從 1 到 n 逐一編號,每個礦石都有自己的重量 wi 以及價值 vi。
檢驗礦產的流程是:
1、給定 m 個區間[Li,Ri];
2、選出一個引數 W;
3、對於一個區間[Li,Ri],計算礦石在這個區間上的檢驗值 Yi :
這批礦產的檢驗結果 Y 為各個區間的檢驗值之和。
即: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]的兩個端點 Li 和 Ri。
注意:不同區間可能重合或相互重疊。
輸出格式
輸出一個整數,表示所求的最小值。
資料範圍
1≤n,m≤200000,
0<wi,vi≤106,
0<S≤1012,
1≤Li≤Ri≤n
輸入樣例:
5 3 15
1 5
2 5
3 5
4 5
5 5
2 4
3 3
輸出樣例:
10
演算法分析
資料為1e6我們需要二分尋找S值,二分的判斷就是Y值.題目是不滿足引數W的時候需要加上加上該點而且需要計數加一,最後算出答案.還有最後一點我們最後二分出的答案不一定是最後的答案,我們尋找的是絕對值最小,所以需要判斷二分出的點後後面一個點
程式碼實現
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
ll n,m,s;
int L[maxn],R[maxn];
int v[maxn],w[maxn];
ll sum[maxn],cnt[maxn];
ll check(int x)
{
for(int i=1;i<=n;i++)
{
if(w[i]>=x)
{
sum[i]=sum[i-1]+v[i];
cnt[i]=cnt[i-1]+1;
}
else
{
sum[i]=sum[i-1];
cnt[i]=cnt[i-1];
}
}
ll res=0;
for(int i=1;i<=m;i++)
res+=(sum[R[i]]-sum[L[i]-1])*(cnt[R[i]]-cnt[L[i]-1]);
return res;
}
int main()
{
cin>>n>>m>>s;
for(int i=1;i<=n;i++)
{
cin>>w[i]>>v[i];
}
for(int i=1;i<=m;i++)
{
cin>>L[i]>>R[i];
}
int l=0,r=1e6;
while(l<r)
{
int mid=l+r+1>>1;
if(check(mid)>=s) l=mid;
else r=mid-1;
}
ll ans=min(check(l)-s,s-check(l+1));
cout<<ans<<endl;
}