• LibreOJ #6277


    题目链接:#6277. 数列分块入门 1

    题目大意

    给出一个长为 (n) 的数列,以及 (n) 个操作,操作涉及区间加法,单点查值。

    solution

    我们可以用树状数组和线段树来过掉他, 但是这是一道分块的题,那我们就要用分块来 (A) 掉它

    查询操作: 我们可以直接记录一下块的操作,然后查询的时候将原来的元素加上记录的即可

    修改操作: 我们可以让不足块大小的单独处理, 然后每个块一起处理

    Code:

    /**
    *    Author: Alieme
    *    Data: 2020.9.8
    *    Problem: LibreOJ #6277
    *    Time: O()
    */
    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    
    #define int long long
    #define rr register
    
    #define inf 1e9
    #define MAXN 100010
    
    using namespace std;
    
    inline int read() {
    	int s = 0, f = 0;
    	char ch = getchar();
    	while (!isdigit(ch)) f |= ch == '-', ch = getchar();
    	while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
    	return f ? -s : s;
    }
    
    void print(int x) {
    	if (x < 0) putchar('-'), x = -x;
    	if (x > 9) print(x / 10);
    	putchar(x % 10 + 48);
    }
    
    int n, len;
    
    int a[MAXN], s[MAXN], id[MAXN], b[MAXN];
    
    inline void add(int l, int r, int x) {
    	int start = id[l], end = id[r];
    	if (start == end) {
    		for (rr int i = l; i <= r; i++) a[i] += x, s[start] += x;
    		return ;
    	}
    	for (rr int i = l; id[i] == start; i++) a[i] += x, s[start] += x;
    	for (rr int i = start + 1; i < end; i++) b[i] += x, s[i] += len * x;
    	for (rr int i = r; id[i] == end; i--) a[i] += x, s[end] += x;
    }
    
    inline int query(int r) {
    	return a[r] + b[id[r]];
    	// int start = id[l], end = id[r], ans = 0;
    	// if (start == end) {
    	// 	for (rr int i = l; i <= r; i++) ans += a[i] + b[start];
    	// 	return ans;
    	// }
    	// for (rr int i = l; id[i] == start; i++) ans += a[i] + b[start];
    	// for (rr int i = start + 1; i < end; i++) ans += s[i];
    	// for (rr int i = r; id[i] == end; i--) ans += a[i] + b[end];
    	// return ans;
    }
    
    signed main() {
    	n = read();
    	len = sqrt(n);
    	for (rr int i = 1; i <= n; i++) {
    		a[i] = read();
    		id[i] = (i - 1) / len + 1;
    		s[id[i]] += a[i];
    	}
    	while (n--) {
    		int opt = read(), l = read(), r = read(), c = read();
    		if (opt == 0) add(l, r, c);
    		if (opt == 1) cout << query(r) << "
    ";
    	}
    }
    
  • 相关阅读:
    解决Thread 的关闭问题
    使用.NET实现断点续传
    如何将int类型数据转换成byte数组
    怎么样读取Excel表格中的数据(C#.Net)
    .NET平台下WEB应用程序的部署(安装数据库和自动配置)
    ASP.NET程序中常用的三十三种代码
    C#中的类型转换
    解决StreamReader读取中文出现乱码的问题
    C#下的Raw Socket编程实现网络封包监视
    利用键盘钩子在Windows平台下捕获键盘动作
  • 原文地址:https://www.cnblogs.com/lieberdq/p/13641523.html
Copyright © 2020-2023  润新知