zoukankan      html  css  js  c++  java
  • UVA 12299 RMQ with Shifts(线段树:单点更新)

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3720

    题意:给你一个可变的数组A,有两种操作。操作一:shift(i1, i2....in),将数组中这些元素的值变为(A[i2], A[i3]....A[in], A[i1]),操作二:Query(L, R),

    查询A[i](L<=i <=R)的和。

    题中 Each operation is formatted as a string having no more than 30 characters, 暗示每次参与shift操作的元素不多,所以直接可以使用单点更新的方式来解决问题。

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #define maxn 100010
    #define maxl 50
    #define inf 1000000000
    #define LL(x) x<<1
    #define RR(x) x<<1|1
    using namespace std;
    
    typedef long long LL;
    
    //variable define
    
    struct tree
    {
        int l, r;
        int mi;
    };
    
    tree node[maxn<<2];
    int n, m, arr[maxn], tmp[maxl], tot;
    
    //function define
    
    void push_up(int x);
    
    void build_tree(int left, int right, int x);
    
    int query(int left, int right, int x);
    
    void update(int left, int right, int x, int val);
    
    void solve();
    
    bool is_number(char ch);
    
    int main(void)
    {
        while (scanf("%d %d", &n, &m) != EOF)
        {
            tot = 1;
            build_tree( 1, n, 1);
            solve();
        }
        return 0;
    }
    
    void build_tree(int left, int right, int x)
    {
        node[x].l = left;
        node[x].r = right;
        
        if (left == right)
        {
            scanf("%d", &node[x].mi);
            arr[tot++] = node[x].mi;
            return;
        }
        
        int lx = LL(x);
        int rx = RR(x);
        int mid = left + (right - left)/2;
        build_tree(left, mid, lx);
        build_tree(mid + 1, right, rx);
        push_up(x);
    }
    
    void push_up(int x)
    {
        if (node[x].l >= node[x].r)
            return;
        
        int lx = LL(x);
        int rx = RR(x);
        node[x].mi = min( node[lx].mi, node[rx].mi);
    }
    
    void update(int left, int right, int x, int val)
    {
        if (node[x].l == left && node[x].r == right)
        {
            node[x].mi = val;
            return;
        }
        int lx = LL(x);
        int rx = RR(x);
        int mid = node[x].l + (node[x].r - node[x].l)/2;
        if (right <= mid)
            update(left, right, lx, val);
        else if (left > mid)
            update(left, right, rx, val);
        else
        {
            update(left, mid, lx, val);
            update(mid + 1, right, rx, val);
        }
        push_up( x);
    }
    
    int query(int left, int right, int x)
    {
        if (node[x].l == left && node[x].r == right)
        {
            return node[x].mi;
        }
        int mid = node[x].l + (node[x].r - node[x].l)/2;
        int lx = LL(x);
        int rx = RR(x);
        if (right <= mid)
            return query(left, right, lx);
        else if (left > mid)
            return query(left, right, rx);
        else
            return min( query(left, mid, lx), query(mid + 1, right, rx));
    }
    
    void solve()
    {
        char str[40];
        while (m--)
        {
            int x = 0, y = 0, ind;
            scanf("%s", str);
            if (str[0] == 'q')
            {
                ind = 0;
                while (!is_number(str[ind]))
                    ind++;
                x = 0;
                while (is_number(str[ind]))
                {
                    x *= 10;
                    x += str[ind] - '0';
                    ind++;
                }
                while (!is_number(str[ind]))
                    ind++;
                y = 0;
                while (is_number(str[ind]))
                {
                    y *= 10;
                    y += str[ind] - '0';
                    ind++;
                }
                printf("%d
    ", query( x, y, 1));
            }
            else
            {
                ind = 0, tot = 0;
                while (str[ind] != ')')
                {
                    if (is_number(str[ind]))
                    {
                        x = 0;
                        while (is_number(str[ind]))
                        {
                            x *= 10;
                            x += str[ind] - '0';
                            ind++;
                        }
                        tmp[tot++] = x;
                    }
                    else 
                        ind++;
                }
                
                int swap = arr[tmp[0]];
                for (int i = 0; i < tot - 1; ++i)
                    arr[tmp[i]] = arr[tmp[i+1]];
                arr[tmp[tot - 1]] = swap;
                for (int i = 0; i < tot; ++i)
                {
                    update( tmp[i], tmp[i], 1, arr[tmp[i]]);
                }
            }
        }
    }
    
    bool is_number(char ch)
    {
        if (ch >= '0' && ch <= '9')
            return true;
        return false;
    }
  • 相关阅读:
    LeetCode522. 最长特殊序列 II
    docker activiti部署到Linux环境,流程图乱码
    linux docker 命令
    linux 安装docker
    JSON,JSONOBJECT,JSONARRAY 互转
    Python和java 的区别笔记(未完成)
    程序员常读书单整理,附下载地址
    javaweb同一个项目打包两次放在同一个tomcat下
    SSM项目集成Redis
    Chrome浏览器崩溃
  • 原文地址:https://www.cnblogs.com/chuninsane/p/4929254.html
Copyright © 2011-2022 走看看