zoukankan      html  css  js  c++  java
  • 0711 Can you answer these queries I

    线段树,修改,维护区间最大最小、和;

    Description

    维护一个整数序列,支持以下操作:
    1 x v : 将第x个整数的值修改为v;
    2 x y : 查询区间[x,y]之间的最小值;
    3 x y : 查询区间[x,y]之间的最大值;
    4 x y : 查询区间[x,y]内的整数和。

    Input

    输入文件包含多组测试数据。
    对于每组测试数据,第一行为一个整数N(1<=N<=10^5),表示,接下来一行有N个整数,再接下来一行有一个整数M(1<=M<=10^5),表示一共有M个操作。
    数据保证对于查询操作结果均在int的表示范围内。

    Output

    对于每个查询均用一行输出查询的结果。

    Sample Input

    4 1 5 3 4 5 2 2 4 3 1 3 4 1 4 1 3 -3 4 1 4

    Sample Output

    3 5 13 7
    ----------------------------------------------------------------
    # include <stdio.h>
    # include <string.h>
    
    # define N 100005
    # define INF 0x7fffffff
    
    int n, m, D;
    int Max[4 * N], Min[4 * N], Sum[4 * N];
    
    int max(int x, int y)
    {
        return x>y ? x:y;
    }
    
    int min(int x, int y)
    {
        return x<y ? x:y;
    }
    
    void update(int i)
    {
        for (i += D; i ^ 1; i >>= 1)
        {
            Sum[i >> 1] = Sum[i] + Sum[i ^ 1];
            Max[i >> 1] = max(Max[i], Max[i ^ 1]);
            Min[i >> 1] = min(Min[i], Min[i ^ 1]);
        }
    }
    
    int query(int s, int t, int bj)
    {
        int ret;
    
        if (bj == 4) ret = 0;
        else ret = (bj==2 ? INF:-INF);
    
        s += D-1, t += D+1;
        for (; s ^ t ^ 1; s >>= 1, t >>= 1)
        {
            if ((~s) & 0x1)
            {
                if (bj == 4) ret += Sum[s+1];
                else ret = (bj==2 ? min(ret, Min[s+1]):max(ret, Max[s+1]));
            }
            if ( t & 0x1)
            {
                if (bj == 4) ret += Sum[t-1];
                else ret = (bj==2 ? min(ret, Min[t-1]):max(ret, Max[t-1]));
            }
        }
    
        return ret;
    }
    
    void init(void)
    {
        int i, num;
        
        for (D = 1; D < n+2; D <<= 1) ;
        for (i = 0; i <= 2*D+2; ++i)
        {
            Sum[i] = 0;
            Min[i] = INF;
            Max[i] = -INF;
        }
    
        for (i = 1; i <= n; ++i)
        {
            scanf("%d", &num);
            Max[i+D] = Min[i+D] = Sum[i+D] = num;
            update(i);
        }
    }
    
    void solve(void)
    {
        int i, bj, p, q;
    
        scanf("%d", &m);
        for (i = 1; i <= m; ++i)
        {
            scanf("%d%d%d", &bj, &p, &q);
            if (bj == 1) Sum[D+p] = Min[D+p] = Max[D+p] = q, update(p);
            else printf("%d\n", query(p, q, bj));
        }
    }
    
    int main()
    {
        while (~scanf("%d", &n))
        {
            init();
            solve();
        }
    
        return 0;
    }
    ----------------------------------------------------------------
  • 相关阅读:
    Android UI法宝的设计资源的开发
    Ural 1309 Dispute (递归)
    ZOJ3827 ACM-ICPC 2014 亚洲区域赛的比赛现场牡丹江I称号 Information Entropy 水的问题
    myeclipse如何恢复已删除的文件和代码
    在C#主线程和子线程将数据传递给对方如何实现
    SSh框架结构(Struts2.1+Hibernate4.0+Spring3.1)
    基于大数据分析的安全管理平台技术研究及应用【摘录】
    ulimit -t 引起的kill血案
    Oracle RAC 环境下的连接管理
    SMTP协议--在cmd下利用命令行发送邮件
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2586206.html
Copyright © 2011-2022 走看看