首页 > 其他分享 >[楼房重建] 解题报告

[楼房重建] 解题报告

时间:2023-03-25 12:22:52浏览次数:44  
标签:right 楼房 long write 解题 区间 left 重建 define

楼房重建
先搞清楚题目要求的是什么。令 \(k_0=0,k_i=\frac{h_i}{i}\),则题目求的一个从 \(0\) 开始的单调上升序列的长度减一。

最暴力的做法就是直接维护上升的序列,修改后从修改处开始重新维护,但时间复杂度不对,考虑优化。

先忽略从 \(0\) 开始的限制条件。

令 \(mx_{\left[l,r\right]}\) 表示区间 \(\left[l,r\right]\) 内的最大值,对于区间 \(\left[l,k\right]\) 和 \(\left[k+1,r\right]\) 可以发现当 \(mx_{\left[l,k\right]}<mx_{\left[k+1,r\right]}\) 时,区间 \(\left[l,r\right]\) 的答案是区间 \(\left[l,k\right]\) 的答案合并而来的。对于不满足上述条件的区间,可以在 \(\left[k+1,r\right]\) 上找到第一个大于 \(mx_{\left[l,k\right]}\) 的数的位置 \(x\),得到 \(\left[x,r\right]\) 的答案,区间 \(\left[l,r\right]\) 的答案也可以转移得到。既然可以区间合并,考虑线段树。

对于区间 \(\left[l,r\right]\),若 \(l=r\),则有值答案赋为 \(1\),没值答案赋为 \(0\)。否则考虑两个区间最大值之间的关系,按照上述方法合并,只需要找到 \(x\) 就可以了。对于 \(\left[x,y\right]\),因为所有子区间的答案都知道了,若左区间最大值大于要求的值,则右区间对 \(\left[x,y\right]\) 的答案的贡献可以直接计入,再往左区间递归寻找,否则往右区间递归寻找。每次修改之后重新维护答案即可,答案为区间 \(\left[1,n\right]\) 的答案。

点击查看代码
#include<bits/stdc++.h>
#define ull unsigned long long
#define ll long long
#define LD long double
#define pdi pair<double,int>
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define eps 1e-9
using namespace std;
namespace IO{
    template<typename T>
    inline void read(T &x){
        x=0;
        int f=1;
        char ch=getchar();
        while(ch>'9'||ch<'0'){
            if(ch=='-'){
                f=-1;
    }
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            x=x*10+(ch-'0');
            ch=getchar();
        }
        x=(f==1?x:-x);
    }
    template<typename T>
    inline void write(T x){
        if(x<0){
            putchar('-');
            x=-x;
        }
        if(x>=10){
            write(x/10);
        }
        putchar(x%10+'0');
    }
    template<typename T>
    inline void write_endl(T x){
        write(x);
        putchar('\n');
    }
    template<typename T>
    inline void write_space(T x){
        write(x);
        putchar(' ');
    }
}
using namespace IO;
const int N=2e5+10;
int n,q;
namespace Seg_Tree{
    struct node{
        int tot;
        LD mx;
    }tr[N<<2];
    int ls(int p){
        return p<<1;
    }
    int rs(int p){
        return p<<1|1;
    }
    int query(int p,int l,int r,LD mx){
        if(l==r){
            return tr[p].mx>mx;
        }
        int mid=(l+r)>>1;
        if(tr[ls(p)].mx<=mx){
            return query(rs(p),mid+1,r,mx);
        }
        else{
            return query(ls(p),l,mid,mx)+tr[p].tot-tr[ls(p)].tot;
        }
    }
    void update(int p,int l,int r,int pos,LD val){
        if(l==r){
            tr[p].tot=1;
            tr[p].mx=val;
            return;
        }
        int mid=(l+r)>>1;
        if(pos<=mid){
            update(ls(p),l,mid,pos,val);
        }
        else{
            update(rs(p),mid+1,r,pos,val);
        }
        tr[p].mx=max(tr[ls(p)].mx,tr[rs(p)].mx);
        tr[p].tot=tr[ls(p)].tot+query(rs(p),mid+1,r,tr[ls(p)].mx);
    }
}
signed main(){
    #ifndef ONLINE_JUDGE
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
    #endif
    read(n),read(q);
    while(q--){
        int pos,h;
        read(pos),read(h);
        Seg_Tree::update(1,1,n,pos,1.0L*h/pos);
        write_endl(Seg_Tree::tr[1].tot);
    }
    return 0;
}

标签:right,楼房,long,write,解题,区间,left,重建,define
From: https://www.cnblogs.com/luoshen0/p/17254495.html

相关文章

  • [省选联考 2022] 卡牌 解题报告
    作为一道著名题,当然是有必要改一改的。本文会介绍卡牌的两种做法:容斥和FWT。下文将默认读者已经清晰地阅读了题目,没有漏过任何性质和条件。容斥这个做法应该是比较好想......
  • [ [Ynoi2013] 无力回天 NOI2017 ] 解题报告
    [Ynoi2013]无力回天NOI2017首先看到异或,想到能维护异或的东西就那几样(线性基/01trie/数位dp/FWT),再看到求选任意个数后的异或最大值,线性基无疑了。这时再看还要维护什......
  • 【LeetCode动态规划#01】动规入门:求斐波那契数 + 爬楼梯(熟悉解题方法论)
    斐波那契数力扣题目链接(opensnewwindow)斐波那契数,通常用F(n)表示,形成的序列称为斐波那契数列。该数列由0和1开始,后面的每一项数字都是前面两项数字的和。也......
  • 「解题报告」ARC127F ±AB
    首先容易想到\(m\)较大时答案为\(m+1\)。具体的,当\(m\gea+b-1\)时,从任意一个位置出发都可以进行操作,所以答案为\(m+1\)。当\(m\lea+b-2\)时,我们发现,对于......
  • 「ACM 算法实践」[解题报告]组队
    分析因为时间不多了,我一开始只考虑了\(a_i\)互不相等的情况,没想到居然拿到了60昏(正确解法是贪心+优先队列。而不是从「使得人数最少的队伍人数最多」中得到的二分......
  • 「ACM 算法实践」[解题报告]时间管理大师
    分析一开始想着应该要分情况讨论,如果每台电脑的耗电量都小于\(e\),那么可以知道小Q是可以一直学习下去的,如果存在电脑的耗电量大于等于\(e\),贪心的想法是将每台电脑......
  • 「ACM 算法实践」[解题报告]沙滩拾贝
    分析因为是与运算,只有当这\(m\)个数的第\(k\)位上都是\(1\)的时候才能使得最后的数的第\(k\)位为\(1\)。为了让最后的开心程度最大,我们优先将高位取\(1\),也......
  • 「解题报告」ARC128F Game against Robot
    好厉害的题。震撼到了。大部分参考Atcoder计数乱做-苹果蓝17。我的观察能力还是太差,一点条件都观察不出来,连\(p\)固定怎么做都不会。下面令\(n\gets\frac{n}{2......
  • 剑指 Offer 07. 重建二叉树(java解题)
    目录1.题目2.解题思路个人思路3.数据类型功能函数总结4.java代码1.题目输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍......
  • 「解题报告」ARC128E K Different Values
    我还是很菜啊。先考虑判定问题。考虑先找出一些显然的必要条件。记\(m=\suma_i\)。那么我们首先对\(m\)进行分块,每\(k\)个一块,设块数为\(p\),最后一个块的大小为......