首页 > 其他分享 >[lnsyoj2286/luoguP4458/BJOI2018]链上二次求和

[lnsyoj2286/luoguP4458/BJOI2018]链上二次求和

时间:2024-08-20 19:15:59浏览次数:8  
标签:BJOI2018 nonumber int lnsyoj2286 sum len ssum 链上 mod

题意

给定序列 \(a\),要求支持修改与查询操作:修改操作为对区间 \(l,r\) 的每个数 \(+d\),查询操作为给定区间 \(l,r\),要求查询:

\[\sum_{len=l}^r\sum_{i=l}^{n-len+1}\sum_{j=l}^{i+len-1}a_j \]

sol

化简式子(下设 \(sum_i=\sum_{j=1}^i a_j,ssum_i=\sum_{j=1}^i sum_j\)):

\[\begin{align} \nonumber &\sum_{len=l}^r\sum_{i=l}^{n-len+1}\sum_{j=i}^{i+len-1}a_j \\ \nonumber =&\sum_{len=l}^r\sum_{i=l}^{n-len+1}(sum_{i+len-1}-sum_{i-1}) \\ \nonumber =&\sum_{len=l}^r(\sum_{i=l}^{n-len+1}sum_{i+len-1})-(\sum_{i=l}^{n-len+1}sum_{i-1}) \\ \nonumber =&\sum_{len=l}^r (ssum_n-ssum_{len-1}-ssum_{n-len}) \\ \nonumber =&ssum_n \cdot (r - l + 1) - \sum_{len=l}^r ssum_{len-1} - \sum_{len=l}^r ssum_{n-len} \nonumber \end{align} \]

因此,我们只需要维护带有区间修改的前缀前缀和,并支持区间和查询即可。
易得,区间修改 \([l,r]\) 会对 \(sum_i\) 带来的贡献为

\[\Delta sum_i= \left \{ \begin{matrix} &0&(i<l) \\ &d \cdot (i - l + 1) &(l \le i \le r)\\ &d \cdot (r - l + 1) &(i > r) \end{matrix}\right. \]

从而可得,区间修改 \([l, r]\) 会对 \(ssum_i\) 带来的贡献为

\[\Delta ssum_i= \left \{ \begin{matrix} &0&(i<l) \\ &d \cdot \sum_{j=l}^i (j - l + 1) &(l \le i \le r)\\ &d \cdot [(i-r)(r-l+1) + \sum_{j=l}^r (j - l + 1)] &(i > r) \end{matrix}\right. \]

我们将 \([l,r],[r+1,n]\) 两段分别处理,易得在每一段中只有 \(i\) 不同,因此我们可以将每一段写作 \(ai^2 + bi + c\) 的形式,具体地:
在 \([l,r]\) 中:

\[\begin{align} &a=\frac{d}{2} \nonumber \\ &b=\frac{d}{2} \cdot (-2l + 3) \nonumber \\ &c=\frac{d}{2} \cdot (l^2-3l+2) \nonumber \end{align} \]

在 \([r + 1,n]\) 中:

\[\begin{align} &a=0 \nonumber \\ &b= d \cdot (r - l + 1) \nonumber \\ &c= d \cdot (\sum_{i=1}^{r - l + 1}i - r ( r - l + 1)) \nonumber \\ \end{align} \]

这样,我们就可以通过维护 \(a,b,c\) 的方式,计算出区间和。

代码

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;
typedef long long LL;
const int N = 200005, mod = 1e9 + 7, INV2 = 500000004, INV6 = 166666668;

int tr[N * 4], la[N * 4], lb[N * 4], lc[N * 4];
int n, m;
int a[N];

int sum1(int x){
    return (LL) x * (x + 1) % mod * INV2 % mod;
}

int sum2(int x){
    return (LL) x * (x + 1) * (2 * x + 1) % mod * INV6 % mod;
}

void pushup(int u){
    tr[u] = (tr[u << 1] + tr[u << 1 | 1]) % mod;
}

void pushdown(int u, int l, int r){
    int mid = l + r >> 1;
    if (l != r){
        la[u << 1] = (la[u << 1] + la[u]) % mod;
        la[u << 1 | 1] = (la[u << 1 | 1] + la[u]) % mod;
        lb[u << 1] = (lb[u << 1] + lb[u]) % mod;
        lb[u << 1 | 1] = (lb[u << 1 | 1] + lb[u]) % mod;
        lc[u << 1] = (lc[u << 1] + lc[u]) % mod;
        lc[u << 1 | 1] = (lc[u << 1 | 1] + lc[u]) % mod;
        tr[u << 1] = (((LL) la[u] * (sum2(mid) - sum2(l - 1)) % mod + (LL) lb[u] * (sum1(mid) - sum1(l - 1)) % mod + (LL) lc[u] * (mid - l + 1) + tr[u << 1]) % mod + mod) % mod;
        tr[u << 1 | 1] = (((LL) la[u] * (sum2(r) - sum2(mid)) % mod + (LL) lb[u] * (sum1(r) - sum1(mid)) % mod + (LL) lc[u] * (r - mid) + tr[u << 1 | 1]) % mod + mod) % mod;
    }
    la[u] = lb[u] = lc[u] = 0;
}

void build(int u, int l, int r){
    if (l == r) {
        tr[u] = a[l];
        la[l] = lb[l] = lc[l];
        return ;
    }

    int mid = l + r >> 1;
    build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
    pushup(u);
}

void update(int u, int l, int r, int L, int R, int a, int b, int c){
    if (L <= l && r <= R){
        tr[u] = (((LL) a * (sum2(r) - sum2(l - 1)) % mod + (LL) b * (sum1(r) - sum1(l - 1)) % mod + (LL) c * (r - l + 1) + tr[u]) % mod + mod) % mod;
        la[u] = (la[u] + a) % mod, lb[u] = (lb[u] + b) % mod, lc[u] = (lc[u] + c) % mod;
        return ;
    }

    pushdown(u, l, r);

    int mid = l + r >> 1;
    if (L <= mid) update(u << 1, l, mid, L, R, a, b, c);
    if (R > mid) update(u << 1 | 1, mid + 1, r, L, R, a, b, c);

    pushup(u);
}

int query(int u, int l, int r, int L, int R){
    if (!L) L = 1;
    if (L > R) return 0;
    if (L <= l && r <= R) return tr[u];
    pushdown(u, l, r);

    int mid = l + r >> 1, res = 0;
    if (L <= mid) res = (res + query(u << 1, l, mid, L, R)) % mod;
    if (R > mid) res = (res + query(u << 1 | 1, mid + 1, r, L, R)) % mod;

    return res;
}

void modify(int l, int r, int d){
    update(1, 1, n, l, r, (LL) d * INV2 % mod, ((LL) d * (((3 - 2 * l) % mod + mod) % mod) % mod * INV2 % mod + mod) % mod, ((LL) d * ((LL) l * l - 3 * l + 2) % mod * INV2 % mod + mod) % mod);
    if (n > r) update(1, 1, n, r + 1, n, 0, (LL) d * (r - l + 1) % mod, ((LL) d * (sum1(r - l + 1) - (LL) r * (r - l + 1) % mod) % mod + mod) % mod);
}

int get_ans(int l, int r){
    return (((LL) query(1, 1, n, n, n) * (r - l + 1) % mod - query(1, 1, n, l - 1, r - 1) - query(1, 1, n, n - r, n - l)) % mod + mod) % mod;
}

int main(){
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
    for (int i = 1; i <= n; i ++ ) a[i] = (a[i - 1] + a[i]) % mod;
    for (int i = 1; i <= n; i ++ ) a[i] = (a[i - 1] + a[i]) % mod;

    build(1, 1, n);

    while (m -- ){
        int op, l, r;
        scanf("%d%d%d", &op, &l, &r);
        if (l > r) swap(l, r);
        if (op == 1){
            int d;
            scanf("%d", &d);
            modify(l, r, d);
        }
        else printf("%d\n", get_ans(l, r));
    }

    return 0;
}

标签:BJOI2018,nonumber,int,lnsyoj2286,sum,len,ssum,链上,mod
From: https://www.cnblogs.com/XiaoJuRuoUP/p/-/lnsyoj2286_luoguP4458

相关文章

  • 链上数据解读Crypto x AI的潜力
    随着CryptoxAI领域迎来越来越多的项目,我们开始看到加密技术与人工智能技术是如何在链上协同工作的。大部分链上交易将由AI智能体来完成。这一趋势在Autoolas的预测市场智能体中表现很明显。自今年年初以来,智能体交易量增长了两倍,过去一个月里,周交易量超过38k,并且,大约63%的交易为......
  • 调用了这么久的JS方法是长在对象、类、值本身还是原型链上?
    调用了这么久的JS方法是长在对象、类、值本身还是原型链上?JavaScript这门语言总是能带给我惊喜,在敲代码的时候习以为常的写法,退一步再看看发现自己其实对很多基操只有表面的使用,而从来没思考过为何要这样操作。今天整理JS代码的时候突然发出灵魂三连问:为什么有些时候操作对象,......
  • 探索Solana链上DApp开发:高性能区块链生态的新机遇
    Solana是一个新兴的区块链平台,致力于为DApp(去中心化应用程序)开发者提供高性能、低成本的解决方案。Solana的独特之处在于其创新性的共识机制和高吞吐量的网络,使得开发者可以构建高度可扩展的DApp,并为用户提供无与伦比的体验。以下是一份简要介绍,让您可以快速了解Solana链......
  • 洛谷 P4429 [BJOI2018] 染色
    洛谷传送门LOJ传送门非常有趣的结论题。首先显然,整个图不是二分图就无解。然后显然每个连通块独立,可以分连通块判定。然后发现一度点是没什么用的,因为无论和它相连的点颜色是什么,它都能找到一种和这种颜色不同的颜色。所以考虑类似拓扑排序剥一度点。剩下的图的\(deg_u\ge......
  • 区块链链上交互基础概念
    1.RPC(远程过程调用)RPC(RemoteProcedureCall)RPC,即远程过程调用,是一种强大的技术,它允许一个计算机上的程序在另一台位于不同位置的计算机上执行过程。在区块链的背景下,RPC成为与区块链节点交互的重要工具。RPC,orRemoteProcedureCall,isapowerfultechnologythatena......
  • P4429 [BJOI2018] 染色
    题面传送门这么牛的结论题!分别考虑每个联通块,不断去掉一度点显然不影响,我们依次给出几个手玩的结论:性质1:如果有奇环,那么无解。只需要给奇环上的集合全部赋值\(\{0,1\}\)即可。性质2:若存在两个环的边不相交,那么无解。考虑一个环,取其对称的两个点,分别记为\(p,q\)。令\(......
  • DevOps|产研运协作工具链上的皇冠-项目管理工具
    项目管理工具可以说是产研运工具链上最耀眼的明星,也是产研工作最重要的一环(没有之一)。为什么这样说?对于我们每个角色(产品、研发、测试、运维、运营、客服等)我们都可以有各自的专业工具来支撑,能让我们每个角色的工作效率很高,但是我们终究是一个为了共同的目标在一起努力的团队。时间......
  • 在以太坊区块链上添加一个区块
    包括json库的相关读取,proof-of-work算法的实现,MerkelTree的构建,使用hash创建新块等内容,使用本地json文件模拟mempool和blockchain,C++编写。#include<iostream>#include<fstream>#include<string>#include<nlohmann/json.hpp>#include<zlib.h>#include<openssl/......
  • 教你轻松查找Coinbase layer2 base链上的新上线项目
    作为Coinbaselayer2的base链自出生就自带光环,目前base链还没有发行代币的计划,后续是否会发行代币已经怎样获取空投资格,我们会随时关注并及时更新。本期主要讲解怎样查找base上新上线的代币,分析代币的流动性、交易情况、合约安全性综合判断代币的投资等级为代币的价值提供一个客观......
  • 最新版多语言BNB链上智能合约区块链高手可以研究研究
    demo软件园每日更新资源,请看到最后就能获取你想要的:1.多语言BNB链上智能合约区块链别人发的我没啥用,还有前面发的和这个好像不一样自己需要的下载玩,这个本来就没有后台,别下载了找我说不完整。看着还是挺不错的。这玩意好像还有人改盗u页面效果:1.数据挖掘与预测分析数......