zoukankan      html  css  js  c++  java
  • ●洛谷 P3616 富金森林公园

    题链:

    树状数组,,,
    本题思路挺巧妙。
    考虑这种暴力算法:(设H[i]为i位置的高度,水面的高度为B)
    从左枚举到右,如果 H[i-1]<B<=H[i],那么就可以贡献答案,即 ANS++。
    基于上述暴力,可以得出:
    如果 H[i-1] < H[i],且询问的 B 在这两个H值之间,则会贡献答案。
    所以,用数据结构维护区间修改(把区间H[i-1]+1~H[i]的值加一)和单点查询(查询当前的水面高度B的ANS)即可。
    代码:
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN 200500
    using namespace std;
    int H[MAXN],tmp[MAXN*3];
    int N,M,tnt;
    struct Question{
    	int a,b,c;
    }Q[MAXN];
    struct BIT{
    	int A[MAXN*3],len;
    	void Reset(int n){
    		len=n; memset(A,0,sizeof(A));
    	}
    	int Lowbit(int x){return x&-x;}
    	void Modify(int l,int r,int x){
    		r++;
    		while(l<=len) A[l]+=x,l+=Lowbit(l);
    		while(r<=len) A[r]-=x,r+=Lowbit(r);
    	}
    	int Query(int p){
    		static int ret; ret=0;
    		while(p) ret+=A[p],p-=Lowbit(p);
    		return ret;
    	}
    }DT;
    int main(){
    	scanf("%d%d",&N,&M); tmp[++tnt]=0;
    	for(int i=1;i<=N;i++) scanf("%d",&H[i]),tmp[++tnt]=H[i];
    	for(int i=1;i<=M;i++){
    		scanf("%d",&Q[i].a);
    		if(Q[i].a==1) scanf("%d",&Q[i].b),tmp[++tnt]=Q[i].b;
    		else scanf("%d%d",&Q[i].b,&Q[i].c),tmp[++tnt]=Q[i].c;
    	}
    	sort(tmp+1,tmp+tnt+1);
    	tnt=unique(tmp+1,tmp+tnt+1)-tmp-1;
    	DT.Reset(tnt); H[0]=lower_bound(tmp+1,tmp+tnt+11,H[0])-tmp;
    	for(int i=1;i<=N;i++){
    		H[i]=lower_bound(tmp+1,tmp+tnt+1,H[i])-tmp;
    		if(H[i]>H[i-1]) DT.Modify(H[i-1]+1,H[i],1);
    	}
    	for(int i=1;i<=M;i++){
    		if(Q[i].a==1){
    			Q[i].b=lower_bound(tmp+1,tmp+tnt+1,Q[i].b)-tmp;
    			printf("%d
    ",DT.Query(Q[i].b));
    		}
    		else{
    			if(H[Q[i].b]>H[Q[i].b-1]) DT.Modify(H[Q[i].b-1]+1,H[Q[i].b],-1);
    			if(H[Q[i].b+1]>H[Q[i].b]) DT.Modify(H[Q[i].b]+1,H[Q[i].b+1],-1);
    			H[Q[i].b]=lower_bound(tmp+1,tmp+tnt+1,Q[i].c)-tmp;
    			if(H[Q[i].b]>H[Q[i].b-1]) DT.Modify(H[Q[i].b-1]+1,H[Q[i].b],1);
    			if(H[Q[i].b+1]>H[Q[i].b]) DT.Modify(H[Q[i].b]+1,H[Q[i].b+1],1);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    skynet源码分析之socketchannel
    skynet源码分析之master/salve集群模式
    skynet源码分析之网络层——网关服务器
    Android反编译基础(apktoos)--广工图书馆APK
    Android-Native-Server 启动和注册详细分析
    Android NDK r8 windows环境搭建
    Android 4.1.1源码编译
    Android Binder------ServiceManager启动分析
    更改系统盘符后DFS无法复制故障处理
    Centos6.9部署Gitlab-11.9.8并汉化
  • 原文地址:https://www.cnblogs.com/zj75211/p/8093172.html
Copyright © 2011-2022 走看看