1. 程式人生 > >離散+二分+字首和 [NOIP2011] 聰明的質監員

離散+二分+字首和 [NOIP2011] 聰明的質監員

[NOIP2011] 聰明的質監員

時間限制:1 s   記憶體限制:128 MB

【問題描述】 
小 T 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有n個礦石,從 1 到n逐一編號,每個礦石都有自己的重量wi以及價值vi。檢驗礦產的流程是: 
1. 給定 m個區間[Li,Ri]; 
2. 選出一個引數W; 
3. 對於一個區間[Li,Ri],計算礦石在這個區間上的檢驗值Yi: 

Yi=j1×jvj,j[Li,Ri]wjW,j

這批礦產的檢驗結果Y為各個區間的檢驗值之和。即:

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

【輸入】 
輸入檔案 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 後來想到樹狀數組差