zoukankan      html  css  js  c++  java
  • 【线段树】hihocoder 1586 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 I. Minimum

    题意:给你一个序列(长度不超过2^17),支持两种操作:单点修改;询问区间中最小的ai*aj是多少(i可以等于j)。

    只需要线段树维护区间最小值和最大值,如果最小值大于等于0,那答案就是minv*minv;

    如果最大值小于等于零,那么答案就是maxv*maxv;

    要是最小值小于零,最大值大于零,答案就是minv*maxv。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    #define N 140000
    int maxv[N<<2],minv[N<<2];
    int T,n;
    void buildtree(int rt,int l,int r){
    	if(l==r){
    		scanf("%d",&minv[rt]);
    		maxv[rt]=minv[rt];
    		return;
    	}
    	int m=(l+r>>1);
    	buildtree(rt<<1,l,m);
    	buildtree(rt<<1|1,m+1,r);
    	maxv[rt]=max(maxv[rt<<1],maxv[rt<<1|1]);
    	minv[rt]=min(minv[rt<<1],minv[rt<<1|1]);
    }
    void update(int p,int v,int rt,int l,int r){
    	if(l==r){
    		minv[rt]=maxv[rt]=v;
    		return;
    	}
    	int m=(l+r>>1);
    	if(p<=m){
    		update(p,v,rt<<1,l,m);
    	}
    	else{
    		update(p,v,rt<<1|1,m+1,r);
    	}
    	maxv[rt]=max(maxv[rt<<1],maxv[rt<<1|1]);
    	minv[rt]=min(minv[rt<<1],minv[rt<<1|1]);
    }
    int qmin(int ql,int qr,int rt,int l,int r){
    	if(ql<=l && r<=qr){
    		return minv[rt];
    	}
    	int m=(l+r>>1),res=2147483647;
    	if(ql<=m){
    		res=min(res,qmin(ql,qr,rt<<1,l,m));
    	}
    	if(m<qr){
    		res=min(res,qmin(ql,qr,rt<<1|1,m+1,r));
    	}
    	return res;
    }
    int qmax(int ql,int qr,int rt,int l,int r){
    	if(ql<=l && r<=qr){
    		return maxv[rt];
    	}
    	int m=(l+r>>1),res=-2147483647;
    	if(ql<=m){
    		res=max(res,qmax(ql,qr,rt<<1,l,m));
    	}
    	if(m<qr){
    		res=max(res,qmax(ql,qr,rt<<1|1,m+1,r));
    	}
    	return res;
    }
    int q;
    int main(){
    	int op,x,y;
    	scanf("%d",&T);
    	for(;T;--T){
    		scanf("%d",&n);
    		n=(1<<n);
    		memset(minv,0,sizeof(minv));
    		memset(maxv,0,sizeof(maxv));
    		buildtree(1,1,n);
    		scanf("%d",&q);
    		for(int i=1;i<=q;++i){
    			scanf("%d%d%d",&op,&x,&y);
    			if(op==1){
    				++x; ++y;
    				int minn=qmin(x,y,1,1,n);
    				int maxx=qmax(x,y,1,1,n);
    				if(minn>=0){
    					printf("%lld
    ",(ll)minn*(ll)minn);
    				}
    				else if(maxx<=0){
    					printf("%lld
    ",(ll)maxx*(ll)maxx);
    				}
    				else{
    					printf("%lld
    ",(ll)minn*(ll)maxx);
    				}
    			}
    			else{
    				++x;
    				update(x,y,1,1,n);
    			}
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    Python内置模块02
    Python常用模块
    hdu 5943(素数间隔+二分图匹配)
    poj 3372(找规律)
    poj 2369(置换群)
    poj 3270(置换群+贪心)
    bzoj 4034(DFS序+线段树)
    poj 2337(单向欧拉路的判断以及输出)
    poj 1041(字典序输出欧拉回路)
    csu 1798(树上最远点对,线段树+lca)
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7583431.html
Copyright © 2011-2022 走看看