求助做法
查看原帖
求助做法
837888
Fractured_Angel楼主2024/3/3 12:03

写了个做法 86pts86pts TLE。思路大概类似单调栈(?)。就是说你前面的人比你高,你就不可能吃到任何东西,因为你前面的人身高是单调不减的,你能吃到的他都能吃到。于是就可以把这头奶牛删去再进行下一个操作。代码就是用双向链表实现删除。求复杂度为什么假了。

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
const LL MAXN = 200005;
struct Node 
{
	LL id, pre, nex, heig;
	bool flag;
} Lis[MAXN];
LL n, m, tot = 0, head = 1;
LL A[MAXN], ans[MAXN];
void Add(LL id, LL heig)
{
	tot ++;
    Lis[tot].pre = tot - 1;
	Lis[tot - 1].nex = tot;
	Lis[tot].id = id;
	Lis[tot].heig = heig; 
    Lis[tot].flag = false;
	return;
}
void Dele(LL id)
{
	Lis[Lis[id].pre].nex = Lis[Lis[id].nex].id;
	Lis[Lis[id].nex].pre = Lis[Lis[id].pre].id;
	Lis[id].flag = true;
	while(Lis[head].flag && head <= n) head ++;
	return;
}
int main()
{
	scanf("%lld%lld", &n, &m);
	LL tmp;
    Lis[0].heig = 0;
    Lis[n + 1].heig = 0;
	for(LL i = 1; i <= n; i ++) 
	{
		scanf("%lld", &tmp);
		Add(i, tmp);
	}
	for(LL i = 1; i <= m; i ++) scanf("%lld", &A[i]);
	LL nowbottom = 1;
	for(LL i = 1; i <= m; i ++)
	{
		// cout << head << endl;
        LL cur = head;
		do
		{
			// cout << cur << " " << Lis[cur].pre << endl;
            if(Lis[cur].heig <= Lis[Lis[cur].pre].heig)
			{
				// cout << Lis[cur].heig << " " << Lis[Lis[cur].pre].heig << endl;
                Dele(cur);
				ans[Lis[cur].id] = Lis[cur].heig;
				cur = Lis[Lis[cur].pre].nex;
			} 
			else cur = Lis[cur].nex;
		} while(cur);
		nowbottom = 1;
		cur = head;
		do
		{
			if(Lis[cur].heig >= nowbottom)
			{
				LL nt = nowbottom;
				nowbottom = min(A[i], Lis[cur].heig) + 1;
				Lis[cur].heig += min(A[i], Lis[cur].heig) - nt + 1;
			}
			cur = Lis[cur].nex;
		} while(cur && nowbottom <= A[i]);
	}
	LL cur = head;
	do
	{
		ans[Lis[cur].id] = Lis[cur].heig;
		cur = Lis[cur].nex;
	} while(cur);
	for(LL i = 1; i <= n; i ++) printf("%lld\n", ans[i]);
	return 0;
}
2024/3/3 12:03
加载中...