LOJ6283 数列分块入门 7 (分块 区间加/乘)题解

题意:区间加,区间乘,单点询问

思路:假设一个点为a,那么他可以表示为m * a + sum,所以区间加就变为m * a + sum + sum2,区间乘变为m * m2 * a + sum * m2。左右两边的块要先puhs down。

代码:

#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5 + 10;
const int M = maxn * 30;
const ull seed = 131;
const int INF = 0x3f3f3f3f;
const int MOD = 1e4 + 7;
struct Block{
    int l, r;
}b[maxn];
int a[maxn], sum[maxn], mult[maxn], belong[maxn];
int n, block;
void down(int bl){
    for(int i = b[bl].l; i <= b[bl].r; i++){
        a[i] = (a[i] * mult[bl] + sum[bl]) % MOD;
    }
    mult[bl] = 1;
    sum[bl] = 0;
}
void add(int l, int r, int c){
    int bl = belong[l], br = belong[r];
    if(bl == br){
        down(bl);
        for(int i = l; i <= r; i++){
            a[i] = (a[i] + c) % MOD;
        }
    }
    else{
        down(bl);
        for(int i = l; i <= b[bl].r; i++){
            a[i] = (a[i] + c) % MOD;
        }
        for(int i = bl + 1; i <= br - 1; i++){
            sum[i] = (sum[i] + c) % MOD;
        }
        down(br);
        for(int i = b[br].l; i <= r; i++){
            a[i] = (a[i] + c) % MOD;
        }
    }
}
void mul(int l, int r, int c){
    int bl = belong[l], br = belong[r];
    if(bl == br){
        down(bl);
        for(int i = l; i <= r; i++){
            a[i] = (a[i] * c) % MOD;
        }
    }
    else{
        down(bl);
        for(int i = l; i <= b[bl].r; i++){
            a[i] = (a[i] * c) % MOD;
        }
        for(int i = bl + 1; i <= br - 1; i++){
            mult[i] = (mult[i] * c) % MOD;
            sum[i] = (sum[i] * c) % MOD;
        }
        down(br);
        for(int i = b[br].l; i <= r; i++){
            a[i] = (a[i] * c) % MOD;
        }
    }
}
int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
    }
    block = sqrt(n);
    for(int i = 1; i <= n; i++){
        belong[i] = (i - 1) / block + 1;
    }
    for(int i = 1; i <= belong[n]; i++){
        b[i].l = (i - 1) * block + 1;
        b[i].r = min(n, b[i].l + block - 1);
        sum[i] = 0, mult[i] = 1;
    }
    for(int i = 1; i <= n; i++){
        int o, l, r;
        int c;
        scanf("%d%d%d%d", &o, &l, &r, &c);
        if(o == 0){
            add(l, r, c);
        }
        else if(o == 1){
            mul(l, r, c);
        }
        else{
            int ans = (a[r] * mult[belong[r]] % MOD + sum[belong[r]]) % MOD;
            printf("%d\n", ans);
        }
    }
    return 0;
}

 

posted @ 2019-05-22 13:25  KirinSB  阅读(286)  评论(0编辑  收藏  举报