1445: Pku3245 Sequence Partitioning
Time Limit: 8 Sec Memory Limit: 64 MBSubmit: 102 Solved: 59
[ Submit][ Status][ Discuss]
Description
Input
Output
Sample Input
4 6
4 3
3 5
2 5
2 4
4 3
3 5
2 5
2 4
Sample Output
9
HINT
An available assignment is the first two pairs are assigned into the first part and the last two pairs are assigned into the second part. Then B1 > A3, B1 > A4, B2 > A3, B2 > A4, max{A1, A2}+max{A3, A4} ≤ 6, and minimum max{B1+B2, B3+B4}=9.
Source
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<bitset>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
const int maxn = 1E5 + 10;
typedef long long LL;
const LL INF = 1E15;
struct data{
int Num; LL F,G; data(){}
data(int Num,LL F,LL G): Num(Num),F(F),G(G){}
bool operator < (const data &B) const {return F + G > B.F + B.G;}
};
int n,cnt,head,tail,q[maxn],A[maxn],B[maxn],R[maxn],Max[maxn];
LL m,sum[maxn],f[maxn],g[maxn];
bool inq[maxn];
priority_queue <data> Q;
void Add(int l,int r)
{
++cnt; Max[cnt] = 0;
for (int i = l; i <= r; i++)
sum[cnt] += 1LL * B[i],Max[cnt] = max(Max[cnt],A[i]);
}
LL Get_top()
{
while (!Q.empty())
{
data k = Q.top();
if (!inq[k.Num] || g[k.Num] != k.G) {Q.pop(); continue;}
else return k.F + k.G;
}
return INF + 233LL;
}
bool Judge(LL now)
{
int tmp = q[head = tail = 1] = 0;
while (!Q.empty()) Q.pop();
Q.push(data(0,0,0)); inq[0] = 1;
for (int i = 1; i <= cnt; i++)
{
f[i] = INF; g[i] = 0;
while (sum[i] - sum[tmp] > now) ++tmp;
while (head <= tail && q[head] < tmp)
inq[q[head]] = 0,++head;
while (head <= tail && Max[q[tail]] <= Max[i])
inq[q[tail]] = 0,--tail;
if (head <= tail)
{
g[q[tail]] = Max[i]; inq[q[tail]] = 1;
Q.push(data(q[tail],f[q[tail]],g[q[tail]]));
}
f[i] = Get_top(); q[++tail] = i;
f[i] = min(f[i],f[tmp] + 1LL * Max[q[head]]);
}
return f[cnt] <= m;
}
int getint()
{
char ch = getchar(); int ret = 0;
while (ch < '0' || '9' < ch) ch = getchar();
while ('0' <= ch && ch <= '9')
ret = ret * 10 + ch - '0',ch = getchar();
return ret;
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
cin >> n >> m;
for (int i = 1; i <= n; i++)
Max[i] = A[i] = getint(),B[i] = getint();
for (int i = n - 1; i; i--) Max[i] = max(Max[i],Max[i + 1]);
for (int i = 1; i <= n; i++)
{
int l = i,r = n;
while (r - l > 1)
{
int mid = l + r >> 1;
if (Max[mid] >= B[i]) l = mid;
else r = mid;
}
R[i] = Max[r] >= B[i] ? r : l;
}
int tl = 1,tr = R[1];
for (int i = 2; i <= n; i++)
if (tr < i) {Add(tl,tr); tl = i; tr = R[i];}
else tr = max(tr,R[i]); Add(tl,tr);
for (int i = 1; i <= cnt; i++) sum[i] += sum[i - 1];
LL l,r; l = 0; r = sum[cnt]; Max[0] = ~0U>>1;
while (r - l > 1LL)
{
LL mid = l + r >> 1LL;
if (Judge(mid)) r = mid;
else l = mid;
}
cout << (Judge(l) ? l : r) << endl;
return 0;
}