• 线段树(带删除节点)


    动态最值(minmax.Cpp/c/java)
    (空间限制128M)

    有一个包含n个元素的数组,要求实现以下操作:
    DELETE k:删除位置k上的数。右边的数往左移一个位置。
    QUERY i j:查询位置i~j上所有数的最小值和最大值。

    【输入】(minmax.in)
    输入第一行包含两个数n, m,表示原始数组的元素个数和操作的个数。第二行包括n个数,表示原始数组。以下m行,每行格式为1 k或者2 i j,其中第一个数为1表示删除操作,为2表示询问操作。
    【输出】(minmax.out)
    输出一行,包括两个数,表示该范围内的最小值和最大值。
    【样例输入】
    10 4
    1 5 2 6 7 4 9 3 1 5
    2 2 8
    1 3
    1 6
    2 2 8
    【样例输出】
    2 9
    1 7
    【限制】
    数组中的元素绝对值均不超过109
    第一组:n = 10, 1 分, 时限 0.1s
    第二组:n = 333, 2 分, 时限 0.1s
    第三组:n = 4232,3分, 时限 0.1s
    第四组:n = 6324, 4分, 时限 0.2s
    第五组:n = 9999, 5分, 时限 2s
    第六组:n = 100000, m = 300000, 10分,时限 2s
    第七组:n = 300000, m = 422342, 13分,时限 3s
    第八组:n = 500000, m = 651222, 18分,时限 3s
    第九组:n = 900000, m = 432122, 22分,时限 5s
    第十组:n = 999999,m = 999999,22分,时限 5s

    /************************
       author   : Grant Yuan
       time     : 2014/10/4 18:06
       source   : 十一第二场
       algorithm: 线段树
    *************************/
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #define INF 0x7fffffff
    #define MAX 1000007
    using namespace std;
    
    struct node
    {
    	int l;
    	int r;
    	int Min;
    	int Max;
    	int num;
    };
    node tree[4*MAX];
    int n,m;
    int input[MAX];
    int ansmin,ansmax;
    void build(int left,int right,int root)
    {
    	tree[root].l=left;
    	tree[root].r=right;
    	if(left==right){
    		tree[root].Max=tree[root].Min=input[left];
    		tree[root].num=1;
    		return;
    	}
    	int mid=(left+right)>>1;
    	build(left,mid,root*2);
    	build(mid+1,right,root*2+1);
    	tree[root].Max=max(tree[root*2].Max,tree[root*2+1].Max);
    	tree[root].Min=min(tree[root*2].Min,tree[root*2+1].Min);
    	tree[root].num=tree[root*2].num+tree[root*2+1].num;
    }
    
    void query(int left,int right,int root)
    {
    	if(left==1&&(right==tree[root].num))
    	{
    		ansmin=min(ansmin,tree[root].Min);
    		ansmax=max(ansmax,tree[root].Max);
    		return;
    	}
    	int n1=tree[root*2].num;
    	int n2=tree[root*2+1].num;
    	if(left<=n1&&right>n1) {query(left,n1,root*2); query(1,right-n1,root*2+1);}
    	else if(left<=n1&&right<=n1) query(left,right,root*2);
    	else if(left>n1&&right<=n1+n2) query(left-n1,right-n1,root*2+1);
    
    }
    
    void Delete(int num,int root)
    {
    	if((tree[root].l==tree[root].r))
    	{
    		tree[root].num=tree[root].num-1;
    		tree[root].Min=INF;tree[root].Max=-INF;
    		return;
    	}
    	int n1=tree[root*2].num;
    	int n2=tree[root*2+1].num;
    	if(num<=n1) Delete(num,root*2);
    	else  Delete(num-n1,root*2+1);
    	tree[root].num=tree[root*2].num+tree[root*2+1].num;
    	tree[root].Max=max(tree[root*2].Max,tree[root*2+1].Max);
    	tree[root].Min=min(tree[root*2].Min,tree[root*2+1].Min);
    }
    
    
    int main()
    {
    	freopen("minmax.in", "r",stdin);
        freopen("minmax.out", "w", stdout);
        while(~scanf("%d%d",&n,&m)){
    		for(int i=1;i<=n;i++)
    		{
    			scanf("%d",&input[i]);
    		}
    		for(int i=1;i<=4*n;i++)
    			 tree[i].Min=INF,tree[i].Max=-INF;
    		build(1,n,1);
    		int a,b,c;
    		for(int i=1;i<=m;i++)
    		{
    			scanf("%d",&a);
    			if(a==1){
    				scanf("%d",&b);
    				Delete(b,1);
    			}
    			else if(a==2){
    				ansmin=INF;ansmax=-INF;
    				scanf("%d%d",&b,&c);
    				query(b,c,1);
    				printf("%d %d
    ",ansmin,ansmax);
    			}
    		}
        }
        return 0;
    }
    


     

  • 相关阅读:
    CentOS 6.5 安装 VNC Server
    vs2008出错
    MySQL 尽量避免使用 TIMESTAMP
    excel中生成32位随机id
    库存扣减和锁
    精通 MySQL 索引
    Java代码性能优化
    RocketMQ 消息丢失场景分析及如何解决
    Java 8 的内存结构
    Spring Boot + MyBatis + MySQL 实现读写分离
  • 原文地址:https://www.cnblogs.com/codeyuan/p/4254418.html
Copyright © 2020-2023  润新知