• LOJ #6280. 数列分块入门 4


    LOJ #6280. 数列分块入门 4

    思路&&代码

    区间修改+区间查值

    这个就是在数列分块入门(1)的基础上加了一个(sum[i])

    先分块,把这(n)个数分成(sqrt{n})个块,用(add[i])表示这个块修改值的和(增量标记),用(sum[i])表示这个块内数的和

    如果第一题会了,这个也很容易明白,就不讲了(qwq)

    时间复杂度(O(nsqrt{n}))

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #define int long long
    using namespace std;
    
    const int A = 1e5 + 11;
    
    inline int read() {
    	char c = getchar(); int x = 0, f = 1;
    	for ( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    	for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
    	return x * f;
    }
    
    int n, m, t;
    int a[A], sum[A], add[A], L[A], R[A], pos[A];
    
    void change(int l, int r, int c) {
    	int p = pos[l], q = pos[r];
    	if(p == q) {
    		for(int i = l; i <= r; i++) a[i] += c;
    		sum[p] += (r - l + 1) * c; return;
    	}
    	for(int i = p + 1; i < q; i++) add[i] += c;
    	for(int i = l; i <= R[p]; i++) a[i] += c; sum[p] += (R[p] - l + 1) * c;
    	for(int i = L[q]; i <= r; i++) a[i] += c; sum[q] += (r - L[q] + 1) * c;
    }
    
    int ask(int l, int r, int c) {
    	int ans = 0, p = pos[l], q = pos[r];
    	if(p == q) {
    		for(int i = l; i <= r; i++) ans += a[i], ans %= (c + 1);
    		ans += add[p] * (r - l + 1);
    		return ans % (c + 1);
    	}
    	for(int i = p + 1; i < q; i++) ans += sum[i] + add[i] * (R[i] - L[i] + 1), ans %= (c + 1);
    	for(int i = l; i <= R[p]; i++) ans += a[i], ans %= (c + 1); ans += add[p] * (R[p] - l + 1), ans %= (c + 1);
    	for(int i = L[q]; i <= r; i++) ans += a[i], ans %= (c + 1); ans += add[q] * (r - L[q] + 1), ans %= (c + 1);
    	return ans % (c + 1);
    }
    
    signed main() {
    	n = read();
    	for(int i = 1; i <= n; i++) a[i] = read();
    	t = sqrt(n);
    	for(int i = 1; i <= t; i++) {
    		L[i] = (i - 1) * sqrt(n) + 1;
    		R[i] = i * sqrt(n);
    	}
    	if(R[t] < n) t++, L[t] = R[t - 1] + 1, R[t] = n;
    	for(int i = 1; i <= t; i++) {
    		for(int j = L[i]; j <= R[i]; j++) {
    			pos[j] = i;
    			sum[i] += a[j];
    		}
    	}
    	m = n;
    	while(m--) {
    		int opt, l, r, c;
    		opt = read(), l = read(), r = read(), c = read();
    		if(opt == 0) change(l, r, c);
    		else cout << ask(l, r, c) << "
    ";
    	}
    }
    
  • 相关阅读:
    HTML学习笔记4----更多元素
    USB协议分析
    USB总线介绍
    SPI驱动程序设计
    SPI子系统
    SPI总线介绍和裸机编程分析
    I2C自编设备驱动设计
    I2C用户态驱动设计
    I2C学习
    MTD系统架构和yaffs2使用、Nandflash驱动设计
  • 原文地址:https://www.cnblogs.com/loceaner/p/12210941.html
Copyright © 2020-2023  润新知