離散+二分+字首和 [NOIP2011] 聰明的質監員
[NOIP2011] 聰明的質監員
時間限制:1 s 記憶體限制:128 MB【問題描述】
小 T 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有n個礦石,從
1 到n逐一編號,每個礦石都有自己的重量wi以及價值vi。檢驗礦產的流程是:
1. 給定 m個區間[Li,Ri];
2. 選出一個引數W;
3. 對於一個區間[Li,Ri],計算礦石在這個區間上的檢驗值Yi:
這批礦產的檢驗結果Y為各個區間的檢驗值之和。即:
Y=∑i=1mYi若這批礦產的檢驗結果與所給標準值 S 相差太多,就需要再去檢驗另一批礦產。小 T 不想費時間去檢驗另一批礦產,所以他想通過調整引數 W 的值,讓檢驗結果
【輸入】
輸入檔案 qc.in。
第一行包含三個整數n,m,S,分別表示礦石的個數、區間的個數和標準值。
接下來的n 行,每行2 個整數,中間用空格隔開,第i+1 行表示i 號礦石的重量wi 和價值vi 。
接下來的m 行,表示區間,每行2 個整數,中間用空格隔開,第i+n+1 行表示區間[Li,Ri]的兩個端點Li 和Ri。注意:不同區間可能重合或相互重疊。
【輸出】
輸出檔名為qc.out。
輸出只有一行,包含一個整數,表示所求的最小值。
【輸入輸出樣例】
qc.in
5 3 15
1 5
2 5
3 5
4 5
5 5
1 5
2 4
3 3
qc.out
10
【輸入輸出樣例說明】
當W 選4 的時候,三個區間上檢驗值分別為20、5、0,這批礦產的檢驗結果為25,此時與標準值S 相差最小為10。
【資料範圍】
對於10%的資料,有1≤n,m≤10;
對於30%的資料,有1≤n,m≤500;
對於50%的資料,有1≤n,m≤5,000;
對於70%的資料,有1≤n,m≤10,000;
對於100%的資料,有1≤n,m≤200,000,0 < wi, vi≤10^6,0 < S≤10^12,1≤Li≤Ri≤n。
打暴力明顯能得好多分,但怎麼打都得二分。一定是二分w,但如果r最先設為質量的最大值,然後暴力二分質量有點慢(但是O能過),選的w一定是一個現有質量,可以離散質量後二分下標。
check函式裡可以用字首和維護當前區間的數量。當然也可以用莫隊,(效率加了sqrt(N)),考試時打的這個,但因為有些可以不開ll的開成ll,結果被卡了常數。。我死黨證明能過(他考試時同樣被卡常,默契。。)
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#define ll long long
#define inf (ll)1000000000
using namespace std;
inline ll read()
{
ll sum=0,f=1;char x=getchar();
while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}
while(x>='0'&&x<='9'){sum=sum*10+x-'0';x=getchar();}
return sum*f;
}
struct Q
{
ll l,r;
} q[200005];
ll n,m,s,v[200005],he[200005],Ha[200005],a[200005],b[200005];
ll ans=inf,h,sz,p=1;
void init()
{sort(Ha+1,Ha+n+1);sz=unique(Ha+1,Ha+n+1)-Ha-1;}
int check(int x)
{
ll sum=0,k=0,l=1,r=0,cnt=0;
x=Ha[x];
a[0]=b[0]=0;
for(int i=1;i<=n;i++)
{
a[i]=a[i-1];
b[i]=b[i-1];
if(he[i]>=x)
a[i]+=v[i],b[i]++;
}
for(int i=1;i<=m;i++)
{
k=b[q[i].r]-b[q[i].l-1];
cnt=a[q[i].r]-a[q[i].l-1];
sum+=k*cnt;
}
if(ans==inf)ans=abs(s-sum);
else
ans=min(ans,abs(s-sum));
if(sum==s)
{
printf("0\n");
p=0;
return 1;
}
if(sum<s)return 1;
else return 0;
}
int main()
{
// freopen("qc.in","r",stdin);
// freopen("qc.out","w",stdout);
n=read();m=read();s=read();
for(int i=1;i<=n;i++)Ha[i]=he[i]=read(),v[i]=read();
init();
for(int i=1;i<=m;i++)
{
q[i].l=read();
q[i].r=read();
}
ll l=1,r=sz,mid;
while(l<=r)
{
mid=(l+r)/2;
if(check(mid))r=mid-1;
else l=mid+1;
if(p==0)exit(0);
}
cout<<ans;
}
相關推薦
離散+二分+字首和 [NOIP2011] 聰明的質監員
[NOIP2011] 聰明的質監員 時間限制:1 s 記憶體限制:128 MB 【問題描述】 小 T 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有n個礦石,從 1 到n逐一編號,每個礦石都有自己的重量wi以及價值vi。檢驗礦產的流程是: 1.
noip2011 聰明的質監員 (二分+字首和處理+讀入優化)
第一行包含三個整數n,m,S,分別表示礦石的個數、區間的個數和標準值。 接下來的n行,每行2個整數,中間用空格隔開,第i+1行表示i號礦石的重量wi和價值vi 。 接下來的m行,表示區間,每行2個整數,中間用空格隔開,第i+n+1行表示區間[Li,Ri]的兩個端點Li和Ri。注意:不同區間可能重合或相互重疊
[NOIP2011] 聰明的質監員 二分+字首和
考試的時候打的二分但沒有用字首和維護。但是有個小細節手誤打錯了結果掛掉了。 絕對值的話可能會想到三分,但是注意到w增大的時候y是減小的,所以單調性很明顯,用二分就可以。但注意一個問題,就是二分最後的結果不一定是最優的,只是在它屬於的符號裡是最優的,所以需要最後存正負的最優解
NOIP2011day2 聰明的質檢員(二分+字首和)
題意 n n n 個礦石,每個礦石有 w,v w , v
【實數二分/字首和維護】Best Cow Fences
Poj 2018 Best Cow Fences 實數二分+字首和維護 調了一晚上, 但發現沒什麼注意事項orz 無輸出只因eps定義成了int型QAQ哭唧唧 #include<cstdio> #include<iostream> using namespace st
#DFS序+二分+字首和# Codeforces Round #381 (Div. 1) B. Alyona and a tree
題目連結 B. Alyona and a tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input output&
POJ 3484 二分字首和
Data-mining huge data sets can be a painful and long lasting process if we are not aware of tiny patterns existing within those data sets. One reput
Codeforces Round #381 (Div. 1) B. Alyona and a tree dfs序 二分 字首和
B. Alyona and a tree 題目連線: http://codeforces.com/contest/739/problem/B Description Alyona has a tree with n vertices. The root of the
D - Dull Chocolates Gym - 101991D -離散化-字首和
D - Dull Chocolates Gym - 101991D 題意:給定n*m的圖有k個white的方塊,其餘的全為black,問有多少點(i,j)滿足從(1,1)到(i,j) 這個矩形區域中white的個數為奇數個。
Codeforces Round #247(Div. 2) D. Random Task 二分+字首和
D. Random Task time limit per test 1 second
[二分+字首和]秦騰與教學評估
分析:二分好題,重點是想到字首和驗證 因為位置只有一個,所以這個位置後的字首和都是奇數,前面都是偶數 所以就可以二分位置再驗證了 程式碼: #include<bits/stdc++.h> using namespace std; typedef l
codefores 1073C (二分 + 字首和)
C. Vasya and Robot time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard output Vasya has g
codeforces1073C. Vasya and Robot(二分+字首和)
C. Vasya and Robot time limit per t
Code[vs] 1138— NOIP2011 聰明的質監員 (二分答案+字首和)
題目連結 題意: 有n個礦石,每個礦石有重量和價值兩個引數,質檢員可以調節一個最低重量w,每個區間的檢查值為該區間內重量>=w的礦石價值和 *(重量>=w的個數),求m個區間的檢查值之和 與 標準值s之差的絕對值的最小值 題解: 檢查值之和 只和 w 有
二分查詢字首和(洛谷1314聰明的質監員NOIP2011提高組)
小T 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有 n 個礦石,從 1到n 逐一編號,每個礦石都有自己的重量 wi 以及價值vi 。檢驗礦產的流程是: 1 、給定m 個區間[Li,Ri]; 2 、選出一個引數 W; 3 、對於一個區間[Li,Ri],計算礦石在這
二分查找前綴和(洛谷1314聰明的質監員NOIP2011提高組)
ron min 最小值 一個數 -s 判斷 inf bre sync 小T 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有 n 個礦石,從 1到n 逐一編號,每個礦石都有自己的重量 wi 以及價值vi 。檢驗礦產的流程是: 1 、給定m 個區間[Li,Ri
洛谷1314 聰明的質監員(二分)(字首和)
題目 洛谷1314 聰明的質監員 題解 二分+字首和 很顯然滿足二分性,隨著W的增大,Y會變小,我們要找的是一個abs(S-Y)最小的值。 一開始,我想著把abs拆開來看,討論min(W-Y)和min(Y-W)。後來發現一個更牛逼的做法,只要一次二分,因為是要與S做
聰明的質監員(二分答案,前綴和)
驗證 前綴和 -m lis 2.7 不想 ret memset 包含 題目描述 小T 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有 nnn 個礦石,從 111 到 nnn 逐一編號,每個礦石都有自己的重量 wiw_iwi? 以及價值 viv_ivi? 。檢驗
『NOIP 2011』聰明的質監員(二分答案 + 前綴和)
可能 can 表示 代碼 標準 和數 怎麽 abs load 題目鏈接 題目描述 小T 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有 \(n\) 個礦石,從 \(1\) 到 \(n\) 逐一編號,每個礦石都有自己的重量 \(w_i\) 以及價值 \(v_i\)
洛谷 P1314 聰明的質監員【二分+前綴和】
mes \n cstring namespace 應該 cer space 放棄 getch 真是zz, 題目很顯然是二分W,然後判斷,我一開始是用線段樹維護當前w[i]>W的個數和v(公式就是區間滿足要求的個數*滿足要求的v的和),然後T成70 後來想到樹狀數組差