zoukankan      html  css  js  c++  java
  • 【洛谷】P4198 楼房重建(线段树)

    传送门

    分析

      被线段树按在地上摩擦  先把左边转化成斜率,那么这个题就转化成每次修改一个点的值,输出前缀最大值的个数

      看到标签是线段树,所以还是想想线段树的做法吧

      既然是线段树,那么就要将区间分成两半,那么左半区间可以直接递归下去做,右半区间就要考虑左半区间对它的影响

      左半区间的最大值会对右半区间的前缀最大值的个数造成影响,所以询问时应该带上之前的最大值

      考虑一次询问(l,r,x),表示l前面的数的最大值为x,区间(l,r)内的前缀最大值,那么每次就要输出询问(1,n,0)

      用dp式子转移的思想对询问进行拆分

      设mid=(l+r)/2,mx(l,r)表示l到r内的最大值

      如果x>mx(l,mid),那么就左半区间就不可能存在前缀最大值,(l,r,x)的结果就等于(mid,r,x)

      如果x<=mx(l,mid),那么询问(l,r,x)就可以拆成(l,mid,x)与(mid+1,r,mx(l,mid))。

      注意到(mid+1,r,mx(l,mid))这个东西与x无关,可以在插入值的时候就处理它

      所以对于每个询问(l,r,x)真正需要现场求的是(l,mid,x)或(mid,r,x),每次拆分区间长度减半,可以做到logn的复杂度

      至于每次插入值修改(mid+1,r,mx(l,mid))时,也可以用同样的方法,总共有logn个区间,每个区间处理的复杂度为logn,所以为long^2n的复杂度

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=100005;
    int n,m,vr[maxn<<2];double mx[maxn<<2];
    int que(int id,int l,int r,double L)
    {
        if(l==r)return mx[id]>L?1:0;
        int mid=(l+r)>>1;
        if(L<=mx[id<<1])return que(id<<1,l,mid,L)+vr[id];
        else return que(id<<1|1,mid+1,r,L);
    }
    void fix(int id,int l,int r,int k,double v)
    {
        if(l==r){mx[id]=v;return;}
        int mid=(l+r)>>1;
        k<=mid?fix(id<<1,l,mid,k,v):fix(id<<1|1,mid+1,r,k,v);
        mx[id]=max(mx[id<<1],mx[id<<1|1]);vr[id]=que(id<<1|1,mid+1,r,mx[id<<1]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1,x,y;i<=m;i++)
        scanf("%d%d",&x,&y),
        fix(1,1,n,x,double(y)/double(x)),
        printf("%d
    ",que(1,1,n,0));
    }
  • 相关阅读:
    冰蝎,从入门到魔改
    红蓝对抗——加密Webshell“冰蝎”攻防
    DGA域名的今生前世:缘起、检测、与发展
    DNS隐藏隧道的使用
    DPI (Deep Packet Inspection) 深度包检测技术
    中国菜刀原理
    一句话木马和中国菜刀的结合拿webshell
    十大黑客工具之一——中国菜刀
    十大ATT&CK攻击技战术
    防守方新秘籍:MITRE 发布主动防御指导框架Shield
  • 原文地址:https://www.cnblogs.com/firecrazy/p/11780074.html
Copyright © 2011-2022 走看看