zoukankan      html  css  js  c++  java
  • 树状数组 洛谷P3616 富金森林公园

    P3616 富金森林公园

    题目描述

    博艾的富金森林公园里有一个长长的富金山脉,山脉是由一块块巨石并列构成的,编号从1到N。每一个巨石有一个海拔高度。而这个山脉又在一个盆地中,盆地里可能会积水,积水也有一个海拔高度,所有严格低于这个海拔高度的巨石,就会在水面下隐藏。

    由于地壳运动,巨石的海拔高度可能会随时变化,每次一块的巨石会变成新的海拔高度。当然,水面的高度也会随时发生变化。

    因为有这样奇妙的地质奇观,吸引了很多游客来游玩。uim作为一个游客,可以告诉你此时水位海拔,你得告诉他,能看到有几个连续露出水面的部分。(与水面持平我们也认为是露出)

    输入输出格式

    输入格式:

    第一行两个整数N和M,分别表示N块石头,M个询问。

    接下来一行,N个整数Ai表示每个巨石的初始海拔。

    接下来M行,每行有两个或者三个数,每一行如果第一个数是1,那么后面跟一个Bj,表示水面海拔。如果第一个数是2,后面跟两个整数,Cj和Dj,表示编号Cj的巨石海拔变为Dj。

    输出格式:

    对于每个"1"询问,给出一个整数答案,也就是露出了几部分的山峰。

    好题。不过自己没有想出来。

    首先可以知道这是一道数据结构题。那么我们就要确定自己要维护什么东西。

    看到询问问的是在给定高度之上的,那么我们就可以用树状数组维护每一个山的高度,即树状数组里存的是在这个高度之上的山的数目。

    这样利用差分,我们可以做到区间修改,然后在树状数组内直接单点查询。

    又因为我们树状数组的下标是高度,所以需要离散化一下。

    因为给出了初始高度,所以我们可以O(n)的扫一遍预处理出树状数组的初值。

    对于查询操作,直接O(1)查询即可。

    对于修改操作,我们要考虑当前位置与它前一个和后一个的高度的关系,但是分情况讨论太麻烦了,所以我们可以直接判断之前这三个之间高度差,也就是将之前的树状数组里在这个高度的值全部清空,再判断当前重新加值。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int wx=4000017;
    int maxn;
    inline int read(){
        int sum=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0';ch=getchar();}
        return sum*f;
    }
    int n,m,top;
    int sum[wx],h[wx],st[wx],que[wx],opt[wx];
    void add(int pos,int k){
        for(int i=pos;i<=4000000;i+=(i&-i)){
            sum[i]+=k;
        }
    }
    int query(int x){
        int re=0;
        for(int i=x;i>=1;i-=(i&-i)){
            re+=sum[i];
        }
        return re;
    }
    struct node{
        int pos,v;
    }q[wx];
    int main(){
        n=read();m=read();
        for(int i=1;i<=n;i++){
            h[i]=read();st[++top]=h[i];maxn=max(maxn,h[i]);
        }
        for(int i=1;i<=m;i++){
            opt[i]=read();
            if(opt[i]==1){
                que[i]=read();st[++top]=que[i];
            }
            else{
                q[i].pos=read();
                q[i].v=read();st[++top]=q[i].v;
            }
        }
        sort(st+1,st+1+top);
        for(int i=1;i<=n;i++){
            h[i]=lower_bound(st+1,st+1+top,h[i])-1-st;
        }
        for(int i=1;i<=m;i++){
            if(opt[i]==1){
                que[i]=lower_bound(st+1,st+1+top,que[i])-st-1;
            }
            else {
                q[i].v=lower_bound(st+1,st+1+top,q[i].v)-st-1;
            }
        }
        for(int i=1;i<n;i++){
            if(h[i]>h[i+1]){
                add(h[i+1]+1,1);
                add(h[i]+1,-1);
            }
        }
        for(int i=1;i<=m;i++){
            if(opt[i]==1){
                int ans=query(que[i]);
                if(h[n]>=que[i])ans++;
                printf("%d
    ",ans);
            }
            else{
                if(q[i].pos!=1)if(h[q[i].pos-1]>h[q[i].pos])add(h[q[i].pos]+1,-1),add(h[q[i].pos-1]+1,1);
                if(q[i].pos!=n)if(h[q[i].pos]>h[q[i].pos+1])add(h[q[i].pos+1]+1,-1),add(h[q[i].pos]+1,1);
                h[q[i].pos]=q[i].v;
                if(q[i].pos!=1)if(h[q[i].pos-1]>h[q[i].pos])add(h[q[i].pos]+1,1),add(h[q[i].pos-1]+1,-1);
                if(q[i].pos!=n)if(h[q[i].pos]>h[q[i].pos+1])add(h[q[i].pos+1]+1,1),add(h[q[i].pos]+1,-1);
    //			if(h[q[i].pos]<=h[q[i].pos-1]&&h[q[i].pos]+q[i].v<=h[q[i].pos-1])add(h[q[i].pos]+1,1),add(h[q[i].pos]+q[i].v+1,-1);
    //			if(h[q[i].pos]<=h[q[i].pos-1]&&h[q[i].pos]+q[i].v>h[q[i].pos-1])add(h[q[i].pos],-1),add(h[q[i].pos-1]+1,-1);
    //			if(h[q[i].pos]<h[q[i].pos+1]&&h[q[i].pos]+q[i].v>=h[q[i].pos+1])add(h[q[i].pos]+1,1),add(h[q[i].pos]+q[i].v+1,-1);
    //			if(h[q[i].pos]>=h[q[i].pos+1])add(h[q[i].pos]+1,1),add(h[q[i].pos]+q[i].v+1,-1);
    //			h[q[i].pos]+=q[i].v;
            }
        }
    }
    
  • 相关阅读:
    【CSP2019模拟】题解
    【Codeforces 868 G】— El Toll Caves(类欧几里得)
    【Codeforces 868 G】— El Toll Caves(类欧几里得)
    如何写出规范的代码? 做一名追求极致的软件工程师!
    浏览器原理
    URL(待整合到HTTP书中哦)
    FTP服务器
    background-image 和 img
    XML的总结学习
    逻辑思维 代码逻辑
  • 原文地址:https://www.cnblogs.com/wangxiaodai/p/9758248.html
Copyright © 2011-2022 走看看