HDU

来源:互联网 发布:centos 创建用户 编辑:程序博客网 时间:2024/05/29 04:21

题意:

给定一段序列,更新某个点的值,查询某个区间的最大值;

思路:

首先,这个题的很好的做法应该是线段树,线段树是维护区间最值的很好的数据结构,

这里作为分块算法的入门题,学习一下;

分块 听说很牛逼,还有分块的思想也是很好的,是把问题根据某个条件分割,然后对某一部分进行暴力;  有点类似于哈希

对于这个题,更新和查询的复杂度都是 sqrt() 级别的,


#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<cmath>#include<set>#include<queue>#include<stack>#include<map>#define PI acos(-1.0)#define in freopen("in.txt", "r", stdin)#define out freopen("out.txt", "w", stdout)using namespace std;typedef long long ll;typedef unsigned long long ull;const int maxn = 2e5 + 7, maxd = 500 + 7, mod = 1e9 + 7;const int INF = 0x7f7f7f7f;int n, m, q;char s[3];int a[maxn], id[maxn], max_[maxd];void updata(int pos, int x) {    a[pos] = x;    int t = id[pos];    for(int i = (t-1)*m+1; i <= t*m; ++i)        max_[t] = max( max_[t], x );}int query(int l_, int r_) {    int ans = 0;    if(id[l_] == id[r_]) {        for(int i = l_; i <= r_; ++i)            ans = max( ans, a[i]);    }    else {        int t1 = id[l_]*m, t2 = (id[r_]-1)*m+1;        for(int i = l_; i <= t1; ++i)            ans = max( ans, a[i]);        for(int i = t2; i <= r_; ++i)            ans = max( ans, a[i]);        for(int i = id[l_]+1; i < id[r_]; ++i)            ans = max( ans, max_[i]);    }    return ans;}void init() {    memset(max_, 0, sizeof max_);    for(int i = 1; i <= n; ++i)        id[i] = (i-1) / m + 1;    for(int i = 1; i <= n; ++i) {        scanf("%d", &a[i]);    }    for(int i = 1; i <= n; ++i)         max_[id[i]] = max( max_[id[i]], a[i]);}int main() {    while(~scanf("%d %d", &n, &q) && n) {        m = sqrt(n);        init();        for(int i = 0; i < q; ++i) {            int x, y;            scanf("%s %d %d", s, &x, &y);            if(s[0] == 'Q') {                printf("%d\n", query(x, y));            }            else updata(x, y);        }    }    return 0;}


原创粉丝点击