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;
}
原文地址:https://www.cnblogs.com/chuninsane/p/4929254.html