题目描述

老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。

思路

线段树,打个乘法lazy标记即可

#include <cstdio>
const int maxn = 100000 + 10;
struct Seg { long long l,r,sum,add,mul; } tree[maxn*4];
long long p;
long long n,m;
inline void pushup(long long root) { tree[root].sum = tree[root<<1].sum+tree[root<<1|1].sum; tree[root].sum %= p; }
inline void BuildTree(long long l,long long r,long long root) {
tree[root].l = l;
tree[root].r = r;
tree[root].mul = 1;
if (l == r) {
scanf("%lld",&tree[root].sum);
tree[root].sum %= p;
return;
}
long long mid = l+r>>1;
BuildTree(l,mid,root<<1);
BuildTree(mid+1,r,root<<1|1);
pushup(root);
}
inline void pushdown(long long root) {
if (tree[root].mul != 1) {
tree[root<<1].mul = tree[root<<1].mul*tree[root].mul%p;
tree[root<<1|1].mul = tree[root<<1|1].mul*tree[root].mul%p;
tree[root<<1].add = tree[root<<1].add*tree[root].mul%p;
tree[root<<1|1].add = tree[root<<1|1].add*tree[root].mul%p;
tree[root<<1].sum = tree[root<<1].sum*tree[root].mul%p;
tree[root<<1|1].sum = tree[root<<1|1].sum*tree[root].mul%p;
tree[root].mul = 1;
}
if (tree[root].add != 0) {
tree[root<<1].add = (tree[root<<1].add+tree[root].add)%p;
tree[root<<1|1].add = (tree[root<<1|1].add+tree[root].add)%p;
tree[root<<1].sum = (tree[root<<1].sum+tree[root].add*(tree[root<<1].r-tree[root<<1].l+1))%p;
tree[root<<1|1].sum = (tree[root<<1|1].sum+tree[root].add*(tree[root<<1|1].r-tree[root<<1|1].l+1))%p;
tree[root].add = 0;
}
}
inline void UpdateAdd(long long ql,long long qr,long long l,long long r,long long root,long long x) {
if (ql > r || qr < l) return;
if (ql <= l && qr >= r) {
tree[root].add = (tree[root].add+x)%p;
tree[root].sum = (tree[root].sum+x*(r-l+1))%p;
return;
}
pushdown(root);
long long mid = l+r>>1;
UpdateAdd(ql,qr,l,mid,root<<1,x);
UpdateAdd(ql,qr,mid+1,r,root<<1|1,x);
pushup(root);
}
inline void UpdateMul(long long ql,long long qr,long long l,long long r,long long root,long long x) {
if (ql > r || qr < l) return;
if (ql <= l && qr >= r) {
tree[root].add = tree[root].add*x%p;
tree[root].mul = tree[root].mul*x%p;
tree[root].sum = tree[root].sum*x%p;
return;
}
pushdown(root);
long long mid = l+r>>1;
UpdateMul(ql,qr,l,mid,root<<1,x);
UpdateMul(ql,qr,mid+1,r,root<<1|1,x);
pushup(root);
}
inline long long Query(long long ql,long long qr,long long l,long long r,long long root) {
if (ql > r || qr < l) return 0;
if (ql <= l && qr >= r) return tree[root].sum;
pushdown(root);
long long mid = l+r>>1;
return (Query(ql,qr,l,mid,root<<1)+Query(ql,qr,mid+1,r,root<<1|1))%p;
}
int main() {
scanf("%lld%lld",&n,&p);
BuildTree(1,n,1);
scanf("%lld",&m);
while (m--) {
long long val;
long long op,l,r;
scanf("%lld%lld%lld",&op,&l,&r);
if (op == 1) {
scanf("%lld",&val);
UpdateMul(l,r,1,n,1,val);
} else if (op == 2) {
scanf("%lld",&val);
UpdateAdd(l,r,1,n,1,val);
} else printf("%lld\n",Query(l,r,1,n,1));
}
return 0;
}

【AHOI2009】 维护序列 - 线段树的更多相关文章

  1. BZOJ1798[Ahoi2009]维护序列——线段树

    题目描述     老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成.    有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2 ...

  2. [P2023][AHOI2009]维护序列(线段树)

    题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...

  3. [AHOI2009]维护序列 (线段树)

    题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...

  4. 洛谷 P2023 [AHOI2009]维护序列 || 线段树加法和乘法运算

    原理倒是非常简单.设原数为x,加法的lazytag为b,乘法的lazytag为a,操作数为c,那么原式为ax+b,乘上c后(ax+b)c=(ac)*x+b*c,加上c后(ax+b)+c=ax+(b+c ...

  5. BZOJ 1798 AHOI2009 Seq 维护序列 线段树

    题目大意:维护一个序列,提供三种操作: 1.将区间中每个点的权值乘上一个数 2.将区间中每个点的权值加上一个数 3.求一段区间的和对p取模的值 2631的超^n级弱化版.写2631之前能够拿这个练练手 ...

  6. [BZOJ1798][AHOI2009]Seq维护序列 线段树

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 一眼看过去线段树,事实上就是线段树.对于乘和加的两个标记,我们可以规定一个顺序,比如 ...

  7. 洛谷 P2023 维护序列——线段树

    先上一波题目 https://www.luogu.org/problem/P2023 复习了一波线段树 题目涉及的操作有区间加 区间乘以及区间求和 tips:线段树在传标记的时候 优先传乘法标记再传加 ...

  8. COGS.1272.[AHOI2009]行星序列(线段树 区间加、乘、求和)

    题目链接 //注意取模! #include<cstdio> #include<cctype> using namespace std; const int N=1e5+5; i ...

  9. BZOJ_1798_[AHOI2009]维护序列_线段树

    BZOJ_1798_[AHOI2009]维护序列_线段树 题意:老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: ( ...

随机推荐

  1. linq介绍及工作中应用两例——左联与内联,linq循环方法

    目录 1 linq介绍 1.1 linq产生背景 1.2 linq使用范围 1.3 linq核心程序集 1.4 linq架构图 1.5 linq使用形式对比 1.5.1 linq To Objects ...

  2. 面试题二十二:链表中倒数第k个节点

    方法一:双指针法定义两个指针A.B,A先走k-1步后再一起走,直到A.next==null注意: 1.链表为空 2.链表长度小于k 3.k<=0 当题目是求链表的中间节点时,可以两个指针从开头开 ...

  3. seaborn分类数据可视化:散点图|箱型图|小提琴图|lv图|柱状图|折线图

    一.散点图stripplot( ) 与swarmplot() 1.分类散点图stripplot( ) 用法stripplot(x=None, y=None, hue=None, data=None, ...

  4. 解惑,什么是data-attribute ?

    在接触 Web前端开发的一段时间,有时会去看Google或者百度的源代码,有某些地方定义了 data-key ,这种语法 但是如果你直接去 Google data-key 或 data-item 可能 ...

  5. LQB20180航班时间(sscanf)

    首先找找规律,两者相加除以二. 按格式读入sscanf 按格式输出printf("02d%",m);前导0 #include <iostream> #include & ...

  6. consul与springcloud整合

    1. 服务提供者注册进consul 1.1新建支付服务module cloud-providerconsul-payment8006 1.2 pom.xml <?xml version=&quo ...

  7. TCP 客户端

    """ 创建客户端 绑定服务器ip地址和端口号(端口号是整型) 与服务器建立连接 发送给服务器要发送的数据(转码) 接收服务器返回的数据 关闭客户端 "&quo ...

  8. idea修改maven项目版本号

    1 先安装插件 2 控制台执行命令  mvn build-helper:parse-version versions:set -DnewVersion=1.1-SNAPSHOT versions:co ...

  9. 删除数据-大表根据rowid来删除部分数据

    偶遇需求,大表中需要删除部分数据.分批删除. declare TYPE type_table_rowid IS TABLE OF ROWID INDEX BY BINARY_INTEGER;table ...

  10. 账本APP开发

    服务端开发 好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 前言 我平时喜欢用账 ...