ポータル:
Portal1:Luogu
Portal2:LibreOJ
Portal3:ストランド
説明
小T
彼は鉱物の数の品質を検査するため、最近、責任の品質監督、です。そここれらの鉱物\(N \)から鉱石番目の\(1 \)する\(N \)個々に番号を付け、それぞれの鉱物は、それ自身の重量有する\(w_iを\)の値\(V_I \) 。ミネラル検査プロセスは、次のとおりです。
所与\(m個\)間隔\([L_iを、R_iを] \) 。
パラメータを選択し、\を(W \) 。
間隔のため\([L_iを、R_iを] \) 、鉱物試験値がこの区間で計算される\(Y_I \) 。
これらの鉱物の試験結果\(Y \)各セクションの値をテストすると。すなわち:\(Y_1 + Y_2 + \ cdots + Y_M \) 。
これらの試験結果やミネラルが基準値の与えられた場合には\(S \)あまりにも多くの違いを、あなたはミネラルの別のバッチをチェックしに行く必要があります。小さなTは時間のかかるが、鉱物の別のグループをテストしたくないので、彼は、パラメータを調整したい(W \)\値、標準値に近い可能な限りのテスト結果は、できるだけ多くなるように\(S \)する必要がある場合でも、( - Y \をS)を\絶対的な最小値。最小値を見つけるのに役立つしてください。
入力
最初の行の入力は三つの整数含ま\(N- \)、\ (m個\)、\ (S \)を、各数値は標準値と鉱石間隔の数を表します。
次\(N- \)行、各行\(2 \)スペースで区切られた整数、\(I + 1 \)行が表す\(Iは\)鉱石番号重量\(W_i \)をそして、の値は\(V_I \) 。
次\(Mの\)間隔を表す線、各行\(2 \)整数、スペースで区切られた中間体、\(I + N + 1 \ ) 間隔を表す線\([L_iを、R_iを]を\ ) 2つのエンドポイント\(L_iを\)と\(R_iと\) 。注:異なる間隔が一致又は重複してもよいです。
出力
必要な最小値を示す整数。
サンプル入力
5 3 15
1 5
2 5
3 5
4 5
5 5
1 5
2 4
3 3
サンプル出力
10
サンプル説明
場合\(Wは\される)群から選択される\(4 \) 3つの試験間隔の値であった\(20、5、0 \) 、これらの鉱物試験結果(\ 25 \)を、次いで、標準的な値\(S \)が最小異なる\(10 \)を。
ヒント
ため\(10 \%の\)データの、ある\(1 \ N-LE、M \ル10 \。) 。
ため\(30 \%の\)データの、ある\(1 \ N-LE、M \ル500 \。) 。
ため\(50 \%の\)データがある\(1 \ N-LE、M \ル5,000 \) 。
以下のための\(70 \%の\)データの、ある\(1 \ N-LE 10,000ル\ \ M。) 。
对于\(100 \%の\)的数据、有\(1つの\ K、M、\ 200,000 0 <w_i、V_I \ 10 ^ 6,0 <P 10 ^ {12}、1 L_iを\ \ \ R_iと\ kが\) 。
溶液
この質問に直接\([0、\最大{ W [I]}] \) 二分列挙\(Wある\) 、列挙のそれぞれのための\(W \) 、各試験力算出部値とどこプレフィックスと最適化を使用します。
コード
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
const LL INF = 0x7f7f7f7f7f7f7f7f7f7f;//把ans的初始值设大一点,否则会WA很多
const int MAXN = 200005;
int n, m, w[MAXN], v[MAXN], L[MAXN], R[MAXN];
LL S, l, r, mid, ans, sum1[MAXN], sum2[MAXN];//注意开long long
inline bool check(LL x) {
for (int i = 1; i <= n; i++)
if (x <= w[i]) {//如果符合要求的化
sum1[i] = sum1[i - 1] + 1;
sum2[i] = sum2[i - 1] + v[i];
} else {
sum1[i] = sum1[i - 1];
sum2[i] = sum2[i - 1];
}
LL s = 0;
for (int i = 1; i <= m; i++)
s += (sum2[R[i]] - sum2[L[i] - 1]) * (sum1[R[i]] - sum1[L[i] - 1]);//暴力计算每一个区间,累加起来
if (ans > fabs(s - S)) ans = fabs(s - S);//计算与标准值相差的最小值
if (S > s) return 1; else return 0;
}
int main() {
scanf("%d%d%lld", &n, &m, &S);
for (int i = 1; i <= n; i++) {
scanf("%d%d", &w[i], &v[i]);
if (w[i] > r) r = w[i];//求区间的右边界(取w[i]的最大值)
}
for (int i = 1; i <= m; i++)
scanf("%d%d", &L[i], &R[i]);
r++;
l = 0;
ans = INF;
while (l < r) {
mid = l + r >> 1;//二分枚举
if (check(mid)) r = mid; else l = mid + 1;//如果大于标准值就往降低要求,否则就提高要求
}
printf("%lld\n", ans);
return 0;
}
アタッチメント
テストデータダウンロード:https://www.lanzous.com/i527v3i