ABC372D求调
  • 板块学术版
  • 楼主xxboyxx
  • 当前回复9
  • 已保存回复9
  • 发布时间2024/9/23 22:13
  • 上次更新2024/9/24 13:14:25
查看原帖
ABC372D求调
473256
xxboyxx楼主2024/9/23 22:13

很rz的做法,就是先跑一个优先队列再线段树区间修改,会对从它减一到左边第一个比它大的。

但是不对,求调。

#include<bits/stdc++.h>
#define int long long
using namespace std;
struct node
{
	int l,r,w,f;
};
int n;
int a[1000005];
int b[1000005];
stack<int> s;
node tree[1000005];
void lazy(int k)
{
	if (tree[k].f)
	{
		tree[k*2].f+=tree[k].f;
		tree[k*2+1].f+=tree[k].f;
		tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
		tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);
		tree[k].f=0;
	}
}
void build(int k,int l,int r)
{
	tree[k].l=l;
	tree[k].r=r;
	if (l==r)
		return;
	int mid=(l+r)/2;
	build(k*2,l,mid);
	build(k*2+1,mid+1,r);
}
void update(int k,int x,int y,int z)
{
	if (tree[k].l>=x && tree[k].r<=y)
	{
		tree[k].w+=(tree[k].r-tree[k].l+1)*z;
		tree[k].f+=z;
		return;
	}
	lazy(k);
	int mid=(tree[k].l+tree[k].r)/2;
	if (x<=mid)
		update(k*2,x,y,z);
	if (y>mid)
		update(k*2+1,x,y,z);
	tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
int query(int k,int x)
{
	if (tree[k].l==tree[k].r)
		return tree[k].w;
	lazy(k);
	int mid=(tree[k].l+tree[k].r)/2;
	if (x<=mid)
		return query(k*2,x);
	else
		return query(k*2+1,x);
}
signed main()
{
	cin>>n;
	build(1,1,n);
	for (int i=1;i<=n;i++)
		cin>>a[i];
	for (int i=n;i>=1;i--)
	{
		while (!s.empty() && a[i]>a[s.top()])
		{
			b[s.top()]=i;
			s.pop();
		}
		s.push(i);
	}
	for (int i=1;i<=n;i++)
		if (b[i]==0)
			b[i]=1;
	for (int i=1;i<=n;i++)
		update(1,b[i],i-1,1);
	for (int i=1;i<=n;i++)
		cout<<query(1,i)<<' ';
	return 0;
}
2024/9/23 22:13
加载中...