首页 > 代码库 > 分块基础练习 UESTC 1324

分块基础练习 UESTC 1324

http://acm.uestc.edu.cn/#/problem/show/1324

 

思路:基础分块,这个是一个特别简单的分块,就当做是一个练习了。然后这题也是很简单的单点线段树更新。

技术分享
//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = 1e5 + 5;
///block表示块的大小,num表示一共分成多少个块
///belong表示这个数在哪个块里面,l和r表示左右边界
/*
查询操作的话,如果x和y是在同一个块里面,就暴力。
如果不是在一个块里面的话,先暴力[x, r[belong[x]]],然后再暴力块
然后再暴力[l[belong[y]], y]
*/
int block, num, l[maxn], r[maxn], belong[maxn], n, q;
LL Max[maxn], a[maxn];

void build(){
    block = sqrt(n); num = n / block;
    if (n % block) num++;
    for (int i = 1; i <= num; i++)
        l[i] = (i - 1) * block + 1, r[i] = i * block;
    r[num] = n;
    for (int i = 1; i <= n; i++){
        belong[i] = (i - 1) / block + 1;
    }
}

void update(int x, int y){
    a[x] += y * 1LL;
    Max[belong[x]] = max(Max[belong[x]], a[x]);
}

int query(int x, int y){
    LL ans = 0;
    if (belong[x] == belong[y]){
        for (int i = x; i <= y; i++)
            ans = max(ans, a[i]);
        return ans;
    }
    for (int i = x; i <= r[belong[x]]; i++){
        ans = max(ans, a[i]);
    }
    for (int i = belong[x] + 1; i <= belong[y] - 1; i++)
        ans = max(ans, Max[i]);
    for (int i = l[belong[y]]; i <= y; i++)
        ans = max(ans, a[i]);
    return ans;
}

int main(){
    cin >> n >> q;
    build();
    for (int i = 1; i <= q; i++){
        int op, x, y;
        scanf("%d%d%d", &op, &x, &y);
        if (op == 1) update(x, y);
        else printf("%d\n", query(x, y));
    }
    return 0;
}
View Code

 

分块基础练习 UESTC 1324