題目大意:給你n個物品,每件物品有重量 w 和價值 v,給m個區間,和乙個標準值。(n,m最大200000)
要求找到乙個值x,使得m個所有區間的權值和與標準值的差的絕對值最小。單個區間權值計算公式(數目num=0,價值sum=0,若滿足 wi >= x ,則++num,sum+=vi)
單個區間權值為num*sum
題目思路: 二分+字首和
首先權值和與x是遞減關係,x越大所得值越小,我們容易想到二分,但是m個區間的比較判斷怎麼處理,如果直接模擬,複雜度最大可達 n^2logn 顯然不行
其實我們可以,用字首和的想法,用乙個陣列num 表示1~i 滿足w>=x的個數,sum對應為滿足條件的w對應的v之和,那麼對於區間我們可直接o(1)得值
每次字首處理o(n) ,所以總複雜度 nlogn ,還有此題需用long long 不然wa
#include #include#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define lson root<<1,l,mid
#define rson root<<1|1,mid+1,r
#define fi first
#define se second
#define ping(x,y) ((x-y)*(x-y))
#define mst(x,y) memset(x,y,sizeof(x))
#define mcp(x,y) memcpy(x,y,sizeof(y))
using
namespace
std;
#define gamma 0.5772156649015328606065120
#define mod 1000000007
#define inf 0x3f3f3f3f
#define n 200005
#define maxn 10000500typedef pair
pii;
typedef
long
long
ll;ll n,m;
ll k,sta,l=-1,r,ans=1ll<<62
;struct
nodenode[n];
struct
segseg[n];
ll num[n],sum[n];
bool
match(ll x)
}ll temp=0
;
for(ll i=1;i<=m;++i)
temp=temp-sta;
ans=min(ans,llabs(temp));
return temp>=0;}
intmain()
for(i=1;i<=m;++i)
++r;
while(l<=r)
else r=mid-1
; }
printf(
"%lld\n
",ans);
return0;
}
Vijos P1740聰明的質檢員
小 t 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有n個礦石,從1到n逐一編號,每個礦石都有自己的重量wi以及價值vi。檢驗礦產的流程是 1 給定m個區間 li,ri 2 選出乙個引數w 3 對於乙個區間 li,ri 計算礦石在這個區間上的檢驗值yi yi 1 vj,j li,ri 且...
聰明的質檢員
問題描述 小 t 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有 n 個礦石,從 1 到 n 逐一編號,每個礦石都有自己的重量wi 以及價值vi 檢驗礦產的流程是 1.給定 m個區間 l i,ri 2.選出乙個引數 w 3.對於乙個區間 l i,ri 計算礦石在這個區間上的檢驗值yi y...
聰明的質檢員
題目描述 小t是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有n個礦石,從1到n逐一編號,每個礦石都有自己的重量wi以及價值vi。檢驗礦產的流程見圖。若這批礦產的檢驗結果與所給標準值s相差太多,就需要再去檢驗另一批礦產。小t不想費時間去檢驗另一批礦產,所以他想通過調整引數w的值,讓檢驗結果...