• LibreOJ #6283


    题目链接:#6283. 数列分块入门 7

    题目大意

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

    solution

    我们这题可以借鉴线段树的懒标记, 然后我们的操作就变成了:

    修改操作: 加和: 对于整块直接加和,对于散块,我们懒标记下放,然后暴力加和
    乘: 对于整块,我们更新懒标记,对于散块, 我们下放,然后暴力乘
    查询操作: 我们直接求就好了

    Code:

    /**
    *    Author: Alieme
    *    Data: 2020.9.8
    *    Problem: LiberOJ #6283
    *    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;
    }
    
    const int mod = 10007;
    
    void print(int x) {
    	if (x < 0) putchar('-'), x = -x;
    	if (x > 9) print(x / 10);
    	putchar(x % 10 + 48);
    }
    
    int n, len;
    
    int sum[MAXN], a[MAXN], id[MAXN], mul[MAXN];
    
    inline void pushdown(int x) {
    	if (mul[x] ^ 1) 
    		for (rr int i = (x - 1) * len + 1; i <= min(x * len, n); i++)
    			a[i] = (a[i] * mul[x]) % mod;
    	mul[x] = 1;
    	if (sum[x])
    		for (rr int i = (x - 1) * len + 1; i <= min(x * len, n); i++)
    			a[i] = (a[i] + sum[x]) % mod;
    	sum[x] = 0;
    }
    
    inline void add_sum(int l, int r, int x) {
    	int start = id[l], end = id[r];
    	if (id[l] == id[r]) {
    		pushdown(start);
    		for (rr int i = l; i <= r; i++) a[i] = (a[i] + x) % mod;
    		return ;
    	}
    	pushdown(start), pushdown(end);
    	for (rr int i = l; id[i] == start; i++) a[i] = (a[i] + x) % mod;
    	for (rr int i = start + 1; i < end; i++) sum[i] = (sum[i] + x) % mod;
    	for (rr int i = r; id[i] == end; i--) a[i] = (a[i] + x) % mod;
    }
    
    inline void add_mul(int l, int r, int x) {
    	int start = id[l], end = id[r];
    	if (id[l] == id[r]) {
    		pushdown(start);
    		for (rr int i = l; i <= r; i++) a[i] = (a[i] * x) % mod;
    		return ;
    	}
    	pushdown(start), pushdown(end);
    	for (rr int i = l; id[i] == start; i++) a[i] = (a[i] * x) % mod;
    	for (rr int i = start + 1; i < end; i++) sum[i] = (sum[i] * x) % mod, mul[i] = (mul[i] * x) % mod;
    	for (rr int i = r; id[i] == end; i--) a[i] = (a[i] * x) % mod;
    }
    
    inline int query(int x) {
    	return (a[x] * mul[id[x]] % mod + sum[id[x]]) % mod;
    }
    
    signed main() {
    	n = read();
    	len = sqrt(n);
    	for (rr int i = 1; i <= n; i++) a[i] = read(), a[i] %= mod, id[i] = (i - 1) / len + 1, mul[id[i]] = 1;
    	for (rr int i = 1; i <= n; i++) {
    		int opt = read(), l = read(), r = read(), c = read();
    		if (opt == 0) add_sum(l, r, c);
    		if (opt == 1) add_mul(l, r, c);
    		if (opt == 2) cout << query(r) << "
    ";
    	}
    }
    
  • 相关阅读:
    c# 中HttpClient访问Https网站
    c# ASP.NET Core2.2利用中间件支持跨域请求
    vs2017 .net core 项目调试浏览器网页闪退Bug
    Docker 共有 13 个管理命令和 41 个通用命令,以下是常用 Docker 命令列表
    在C#中GUID生成的四种格式
    Asp.net Image控件显示Bitmap生成图像
    visual studio code常用插件
    初中历史画卷
    google chrome 浏览器插件
    如何幽默
  • 原文地址:https://www.cnblogs.com/lieberdq/p/13641833.html
Copyright © 2020-2023  润新知