• [洛谷P4198]楼房重建(线段树维护单调栈)


    题目

    给一个序列,支持单点修改,每次修改后输出对这个序列做单调递增栈后栈的大小

    思路

    线段树维护单调栈模板题

    先开个线段树,设(query(rt,l,r,x))表示询问([l,r])这段区间中比(x)大的数形成的单调栈大小,(mx[rt])表示该子树中的最大值
    显然有(query(rt,l,r,x) = query(ls,l,mid,x) + query(rs,mid+1,r,mx[ls]))
    每次都递归到底是不行的,考虑用一个中间值存其中一个询问,由于最终询问为(query(1,1,n,0)),设(ans[rt]=query(rt,l,r,0))
    修改时mx显然可以直接(O(1))求的,而(ans)用上面的递推式,只需要快速得到(query(rs,mid+1,r,mx[ls]))即可

    对于询问(query(rt,l,r,x))

    1. (mx[ls]leq x),即左区间没有贡献,直接递归右区间(query(rs,mid+1,r,x))

    2. (mx[ls]>x),左区间有贡献,此时递归左区间(query(ls,l,mid,x)),右区间为(query(rs,mid+1,r,mx[ls])=ans[rt]-ans[ls])

    于是询问只需要递归(log)次,而修改的pushup共需要log次询问,总复杂度为(O(nlog^2n))

    Code

    #include<bits/stdc++.h>
    #define N 100005
    #define Min(x,y) ((x)<(y)?(x):(y))
    #define Max(x,y) ((x)>(y)?(x):(y))
    using namespace std;
    typedef long long ll;
    int n,m,ans[N<<2];
    double mx[N<<2];
    
    template <class T>
    void read(T &x)
    {
    	char c; int sign=1;
    	while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48;
    	while((c=getchar())>='0'&&c<='9') x=(x<<1)+(x<<3)+c-48; x*=sign;
    }
    int query(int rt,int l,int r,double k)//查询大于k情况下单增的单调栈长度 
    {
    	if(l==r) return (mx[rt]>k);
    	if(mx[rt]<=k) return 0;//全部都很小
    	int mid=(l+r)>>1;
    	if(mx[rt<<1]<=k) return query(rt<<1|1,mid+1,r,k);
    	return query(rt<<1,l,mid,k)+ans[rt]-ans[rt<<1];
    }
    void modify(int rt,int l,int r,int x,double val)
    {
    	if(l==r) { ans[rt]=1; mx[rt]=val; return; }
    	int mid=(l+r)>>1;
    	if(x<=mid) modify(rt<<1,l,mid,x,val);
    	else modify(rt<<1|1,mid+1,r,x,val);
    	mx[rt]=Max(mx[rt<<1],mx[rt<<1|1]);
    	ans[rt]=ans[rt<<1]+query(rt<<1|1,mid+1,r,mx[rt<<1]);
    }
    int main()
    {
    	read(n);read(m);
    	while(m--)
    	{
    		int x,y;
    		read(x);read(y);
    		modify(1,1,n,x,1.0*y/x);
    		printf("%d
    ",ans[1]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Code First 迁移
    使用C#创建Windows服务 并发布Windows 服务
    线程(Thread,ThreadPool)、Task、Parallel
    用《捕鱼达人》去理解C#中的多线程
    Visual Studio提示“无法启动IIS Express Web服务器”的解决方法 调试闪退
    防cc攻击策略
    多线程和异步的异同和使用场景
    JQuery Checkbox 获取多选值 Checkbox选中个数
    C# 说说lock到底锁谁?(1)
    C# 说说lock到底锁谁?(2)
  • 原文地址:https://www.cnblogs.com/Chtholly/p/11793219.html
Copyright © 2020-2023  润新知