您的位置:首页 > 产品设计 > UI/UE

[POJ3017] Cut the Sequence && 单调队列

2014-12-06 13:26 435 查看
由于这道题决策点的值并不打掉 所以要搞个平衡树上去(虽然暴力也可以过) 正好操作需求不大 可以直接用multiset搞过去 还有就是G++的STL效率低可能超时 C++快的多

#include<cstdio>
#include<cstring>
#include<deque>
#include<queue>
#include<algorithm>
#include<set>
#include<iostream>
#define MAXN 100000
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
LL d[MAXN+10];
multiset <int> S;
LL A[MAXN+10], sum[MAXN+10];
deque <int> q;
int main()
{
	LL n, K;
	while(scanf("%lld%lld", &n, &K) == 2)
	{
		S.clear(); q.clear();
		bool f = false;
		for(int i = 1; i <= n; i++) 
		{
			scanf("%lld", &A[i]);
			sum[i] = sum[i-1] + A[i];
			if(A[i] > K)
				f = true;
		}
		if(f) {
			cout << "-1\n";
			continue;
		}
		int des = 0;
		for(int i = 1; i <= n; i++)
		{
			while(sum[i] - sum[des] > K) ++des;
			while(!q.empty() && q.front() <= des)
			{
				int F = q.front(); q.pop_front();
				if(!q.empty()) S.erase(d[F] + A[q.front()]);
			}
			while(!q.empty() && A[q.back()] <= A[i])
			{
				int B = q.back(); q.pop_back();
				if(!q.empty()) S.erase(d[q.back()] + A[B]);
			}
			if(!q.empty()) S.insert(d[q.back()] + A[i]);
			q.push_back(i);
			d[i] = d[des] + A[q.front()];
			if(S.size()) d[i] = min(d[i], (LL)(*(S.begin())));
		}
		cout << d
 << '\n';
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: