「模板」 线段树——区间乘 && 区间加 && 区间求和

<题目链接>


原来的代码太恶心了,重贴一遍。

#include <cstdio>
int n,m;
long long p;
class SegmentTree
{
private:
struct Node
{
int l,r;
long long v,mul,add;
Node *c[2];
Node(int l,int r):l(l),r(r),mul(1LL),add(0LL)
{
c[0]=c[1]=nullptr;
}
~Node(void)
{
if(c[0]!=nullptr)
delete c[0];
if(c[1]!=nullptr)
delete c[1];
}
long long Size(void)
{
return (long long)(r-l+1);
}
long long Value(bool p)
{
return c[p]!=nullptr ? c[p]->v : 0;
}
void Modify(long long _mul,long long _add)
{
v=(v*_mul+Size()*_add)%p;
mul=mul*_mul%p;
add=(add*_mul+_add)%p;
}
void MulModify(long long k)
{
v=v*k%p;
mul=mul*k%p;
add=add*k%p;
}
void AddModify(long long k)
{
v=(v+Size()*k)%p;
add=(add+k)%p;
}
void PushUp(void)
{
v=(Value(0)+Value(1))%p;
}
void PushDown(void)
{
if(c[0]!=nullptr)
c[0]->Modify(mul,add);
if(c[1]!=nullptr)
c[1]->Modify(mul,add);
mul=1,add=0;
}
}*rt;
void Build(Node* &i,int l,int r)
{
i=new Node(l,r);
if(l==r)
{
scanf("%lld",&i->v);
return;
}
int mid=l+r>>1;
Build(i->c[0],l,mid);
Build(i->c[1],mid+1,r);
i->PushUp();
}
void Mul(Node* i,int l,int r,long long k)
{
if(l==i->l && r==i->r)
{
i->MulModify(k);
return;
}
i->PushDown();
int mid=i->l+i->r>>1;
if(r<=mid)
Mul(i->c[0],l,r,k);
else if(l>mid)
Mul(i->c[1],l,r,k);
else
{
Mul(i->c[0],l,mid,k);
Mul(i->c[1],mid+1,r,k);
}
i->PushUp();
}
void Add(Node* i,int l,int r,long long k)
{
if(l==i->l && r==i->r)
{
i->AddModify(k);
return;
}
i->PushDown();
int mid=i->l+i->r>>1;
if(r<=mid)
Add(i->c[0],l,r,k);
else if(l>mid)
Add(i->c[1],l,r,k);
else
{
Add(i->c[0],l,mid,k);
Add(i->c[1],mid+1,r,k);
}
i->PushUp();
}
long long Sum(Node* i,int l,int r)
{
if(l==i->l && r==i->r)
return i->v;
i->PushDown();
int mid=i->l+i->r>>1;
if(r<=mid)
return Sum(i->c[0],l,r);
else if(l>mid)
return Sum(i->c[1],l,r);
else
return (Sum(i->c[0],l,mid)+Sum(i->c[1],mid+1,r))%p;
}
public:
SegmentTree(int n):rt(nullptr)
{
Build(rt,1,n);
}
~SegmentTree(void)
{
delete rt;
}
void Mul(int l,int r)
{
long long k;
scanf("%lld",&k);
Mul(rt,l,r,k);
}
void Add(int l,int r)
{
long long k;
scanf("%lld",&k);
Add(rt,l,r,k);
}
void Sum(int l,int r)
{
printf("%lld\n",Sum(rt,l,r));
}
};
int main(int argc,char** argv)
{
scanf("%d %d %lld",&n,&m,&p);
static SegmentTree *T=new SegmentTree(n);
for(int i=1,opt,x,y;i<=m;++i)
{
scanf("%d %d %d",&opt,&x,&y);
switch(opt)
{
case 1:
T->Mul(x,y);
break;
case 2:
T->Add(x,y);
break;
case 3:
T->Sum(x,y);
break;
}
}
delete T;
return 0;
}

谢谢阅读。

「模板」 线段树——区间乘 && 区间加 && 区间求和的更多相关文章

  1. Loj #2570. 「ZJOI2017」线段树

    Loj #2570. 「ZJOI2017」线段树 题目描述 线段树是九条可怜很喜欢的一个数据结构,它拥有着简单的结构.优秀的复杂度与强大的功能,因此可怜曾经花了很长时间研究线段树的一些性质. 最近可怜 ...

  2. 「ZJOI2019」线段树 解题报告

    「ZJOI2019」线段树 听说有人喷这个题简单,然后我就跑去做,然后自闭感++,rp++(雾) 理性分析一波,可以发现最后形成的\(2^k\)个线段树,对应的操作的一个子集,按时间顺序作用到这颗线段 ...

  3. 【LOJ】#3043. 「ZJOI2019」线段树

    LOJ#3043. 「ZJOI2019」线段树 计数转期望的一道好题-- 每个点设两个变量\(p,q\)表示这个点有\(p\)的概率有标记,有\(q\)的概率到祖先的路径上有个标记 被覆盖的点$0.5 ...

  4. LOJ 3043: 洛谷 P5280: 「ZJOI2019」线段树

    题目传送门:LOJ #3043. 题意简述: 你需要模拟线段树的懒标记过程. 初始时有一棵什么标记都没有的 \(n\) 阶线段树. 每次修改会把当前所有的线段树复制一份,然后对于这些线段树实行一次区间 ...

  5. 「ZJOI2019」线段树

    传送门 Description 线段树的核心是懒标记,下面是一个带懒标记的线段树的伪代码,其中 tag 数组为懒标记: 其中函数\(Lson(Node)\)表示\(Node\)的左儿子,\(Rson( ...

  6. @loj - 2093@ 「ZJOI2016」线段树

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 小 Yuuka 遇到了一个题目:有一个序列 a1,a2,..., ...

  7. 【LOJ3043】「ZJOI2019」线段树

    题面 问题可以转化为每次区间覆盖操作有 \(\frac{1}{2}\) 的概率进行,求标记和的期望.于是我们只要求出所有点有标记的概率即可. 我们设 \(f_i\) 表示节点 \(i\) 有标记的概率 ...

  8. @loj - 3043@「ZJOI2019」线段树

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 九条可怜是一个喜欢数据结构的女孩子,在常见的数据结构中,可怜最喜 ...

  9. poj 3468 A Simple Problem with Integers (线段树 成段更新 加值 求和)

    题目链接 题意: 只有这两种操作 C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.&quo ...

随机推荐

  1. POJ 2177 Ghost Busters(三维几何)

    Description The famous Ghost Busters team has decided to upgrade their Ectomobile (aka Ecto-1) with ...

  2. Greedy Gift Givers 贪婪的送礼者

    Description 对于一群要互送礼物的朋友,TRW要确定每个人送出的钱比收到的多多少.在这一个问题中,每个人都准备了一些钱来送礼物,而这些钱将会被平均分给那些将收到他的礼物的人.然而,在任何一群 ...

  3. Thunder团队第一周 - Scrum会议3

    Scrum会议3 小组名称:Thunder 项目名称:在线考试系统 Scrum Master:杨梓瑞 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李 ...

  4. .从列表结束中删除第N个节点

    描述 给定一个链表,从列表的最后删除倒数第n个元素 例如: 给定链表:1-> 2-> 3-> 4-> 5,并且n = 2. 删除倒数第二个,链表将变为1-> 2-> ...

  5. iOS- Apple零配置网络协议Bonjour的使用?

    1.前言 这段时间为了解决公司App的网络离线需求,做了个Apple推出的零配置网络协议Bonjour的Test,主要是为了解决iOS设备的IP获取,之前是可以使用socket的广播来实现,但是使用A ...

  6. 安装配置erlang_db_driver

    erlang-db-driver是北京融易通公司开源的一个erlang支持众多数据库的一个驱动类库,据其wiki介绍,其支持MySQL, Oracle, Sybase, DB2 and Informi ...

  7. Maven jeetsite项目 搭建

    , 一直没有系统的总结一下Maven的知识,今天,想从网上找一个Maven的项目,练练手,顺便学习一下maven的原理 和布局. 官网:http://www.jeesite.com/ 没想到,上来就给 ...

  8. React & `event.persist()`

    React & event.persist() event.persist() https://reactjs.org/docs/events.html#event-pooling Tabs ...

  9. 网页中NPIO对Excel的操作实例

    上一节是在wpf中实现对excel的操作方法,这一节看看网页中如何封装实现对excel的上传导入和下载保存的. 看看效果图:

  10. 【bzoj1076】[SCOI2008]奖励关 期望dp+状态压缩dp

    题目描述 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再 ...