Only maintain the line segment tree of the current interval impact class

Rabbit team teach me line tree / kel

I found this somewhere and wrote a blog to deepen my impression, but the rabbit team's name doesn't have much to do with the actual operation, so I made a name. .

Building reconstruction

Topic: There are \ (n \) buildings, the height of the first \ (i \) building is \ (h_i \) , how many buildings can you see from the \ ((0,0) \) position

You can see if and only if there is no other building between \ ((0,0) \) and \ ((i, h_i) \) , and \ (h_i> 0 \)

\ (h_i \) Support single point modification

solution:

Let \ (s_i = \ frac {h_i} {i} \) , define \ (s_0 = 0 \)

If a building can be seen, \ (s_i \) is the strict prefix maximum value of \ (s \) sequence

Consider using a line segment tree to maintain two values: the maximum value of the interval \ (s_i \) , and only consider the answer under the influence of the interval \ ([l, r] \)

The maximum value is easy to maintain, consider how to merge the two intervals

We found that the left subtree has no effect, the answer can be directly inherited, and the right subtree needs to consider the influence of the left subtree interval

Introduce a function \ (calc \) to merge answers


ans[p]=ans[ls(p)]+calc(mid+1,r,rs(p),maxn[ls(p)]);

inline int calc(int l,int r,int p,int premax)
{
	if(l==r) return (maxn[p]>premax);
	if(maxn[ls(p)]>premax) return calc(l,mid,ls(p),premax)+(ans[p]-ans[ls(p)]);
	return calc(mid+1,r,rs(p),premax);
}

If it is a leaf node, then the information of this node is greater than the maximum value of the prefix and contributes

If the maximum value of the left subtree is greater than the maximum value of the prefix, it means that there are statistic answers in the left subtree plus the total number of answers minus the left subtree answers

Note that the right subtree answer cannot be used directly. The factor right subtree answer does not count the influence of the left subtree interval

If the maximum value of the left subtree is less than or equal to the maximum value of the prefix, then there should be no contribution in the left subtree, directly enter the statistics of the right subtree

Then the combined complexity is a \ (log \) and the total complexity is \ (O (nlog ^ 2n) \)

However, we found that the information maintained by this \ (calc \) function needs to meet the interval decrementability, if it is the interval or the interval's maximum value, it will not work

Reset the state, the answer we maintain becomes the answer of the right subtree under the influence of \ ([l, r] \)

ans[p]=calc(mid+1,r,rs(p),maxn[ls(p)]);

inline int calc(int l,int r,int p,int premax)
{
	if(l==r) return (maxn[p]>premax);
	if(maxn[ls(p)]>premax) return calc(l,mid,ls(p),premax)+ans[p];
	return calc(mid+1,r,rs(p),premax);
}

\ (calc \) can be changed like this without subtraction

Complete code

#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define mid ((l+r)>>1)
#define y1 qwq 
	inline int read()
	{
		int x=0;char ch,f=1;
		for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
		if(ch=='-') f=0,ch=getchar();
		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
		return f?x:-x;
	}
	const int N=1e5+10,inf=1<<30;
	int n,m;
	int h[N];
	int ans[N<<2],sum[N<<2];
	inline bool check(int x,int y)
	{
		if(!y) return h[x];
		return h[x]*y>h[y]*x;
	}
	inline void build(int l,int r,int p)
	{
		ans[p]=l,sum[p]=0;
		if(l==r) return;
		build(l,mid,ls(p));build(mid+1,r,rs(p));
	}
	inline int calc(int l,int r,int p,int pre)
	{
		if(l==r) return check(l,pre);
		if(check(ans[ls(p)],pre)) return calc(l,mid,ls(p),pre)+sum[p];
		return calc(mid+1,r,rs(p),pre);
	}
	inline void update(int pos,int l,int r,int p)
	{
		if(l==r) return;
		if(pos<=mid) update(pos,l,mid,ls(p));
		else update(pos,mid+1,r,rs(p));
		ans[p]=check(ans[rs(p)],ans[ls(p)])?ans[rs(p)]:ans[ls(p)];
		sum[p]=calc(mid+1,r,rs(p),ans[ls(p)]);
	}
	inline void main()
	{
		n=read(),m=read();
		build(1,n,1);
		for(int x,y,i=1;i<=m;++i)
		{
			x=read(),y=read();
			h[x]=y;update(x,1,n,1);
			printf("%lld\n",calc(1,n,1,0));
		}
	}
}
signed main()
{
	red::main();
	return 0;
}

Guess you like

Origin www.cnblogs.com/knife-rose/p/12730154.html