P3373 【模板】线段树 2
387
通过
1.8K
提交
标签
难度 提高+/省选-
提交 讨论 题解

最新讨论 更多讨论

2333
最后三个点卡常数。
迷之RE
感觉这题很迷啊
好像一共三组测试数据。
友情提示:开long long
题目描述

如题,已知一个数列,你需要进行下面两种操作:

1.将某区间每一个数加上x

2.将某区间每一个数乘上x

3.求出某区间每一个数的和

输入输出格式

输入格式:
第一行包含三个整数N、M、P,分别表示该数列数字的个数、操作的总个数和模数。

第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

接下来M行每行包含3或4个整数,表示一个操作,具体如下:

操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k

操作2: 格式:2 x y k 含义:将区间[x,y]内每个数加上k

操作3: 格式:3 x y 含义:输出区间[x,y]内每个数的和对P取模所得的结果

输出格式:
输出包含若干行整数,即为所有操作3的结果。

输入输出样例

输入样例#1:
5 5 38
1 5 4 2 3
2 1 4 1
3 2 5
1 2 4 2
2 3 5 5
3 1 4
输出样例#1:
17
2
说明

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=8,M<=10

对于70%的数据:N<=1000,M<=10000

对于100%的数据:N<=100000,M<=100000

(数据已经过加强^_^)

样例说明:

故输出应为17、2(40 mod 38=2)

思路:

  裸线段树;

来,上代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> #define maxn 100005
#define LL long long using namespace std; struct TreeNodeType {
LL l,r,dis,mid,flag,flag_; bool if_;
};
struct TreeNodeType tree[maxn<<],*lc,*rc; LL if_z,n,m,type,x,p,ans; char Cget; inline void in(LL &now)
{
now=,if_z=,Cget=getchar();
while(Cget>''||Cget<'')
{
if(Cget=='-') if_z=-;
Cget=getchar();
}
while(Cget>=''&&Cget<='')
{
now=now*+Cget-'';
Cget=getchar();
}
now*=if_z;
} void tree_build(LL now,LL l,LL r)
{
tree[now].l=l,tree[now].r=r;
if(l==r)
{
in(tree[now].dis);
return ;
}
tree[now].mid=(l+r)>>;
tree_build(now<<,l,tree[now].mid);
tree_build(now<<|,tree[now].mid+,r);
tree[now].dis=(tree[now<<].dis+tree[now<<|].dis)%p;
} void tree_do(LL now,LL l,LL r)
{
if(tree[now].l==l&&tree[now].r==r)
{
if(type==)
{
tree[now].dis=(tree[now].dis*x)%p;
tree[now].flag=(tree[now].flag*x)%p;
if(tree[now].if_) tree[now].flag_=(tree[now].flag_*x)%p;
else
{
tree[now].if_=true;
tree[now].flag_=x;
}
}
else if(type==)
{
tree[now].flag=(tree[now].flag+x)%p;
tree[now].dis=(tree[now].dis+((r-l+)*x)%p)%p;
}
else ans=(ans+tree[now].dis)%p;
return ;
}
if(tree[now].flag||tree[now].if_)
{
lc=&tree[now<<],rc=&tree[now<<|];
if(tree[now].if_)
{
lc->dis=(lc->dis*tree[now].flag_)%p;
rc->dis=(rc->dis*tree[now].flag_)%p;
lc->flag=(lc->flag*tree[now].flag_)%p;
rc->flag=(rc->flag*tree[now].flag_)%p;
if(lc->if_) lc->flag_=(lc->flag_*tree[now].flag_)%p;
else lc->flag_=tree[now].flag_,lc->if_=true;
if(rc->if_) rc->flag_=(rc->flag_*tree[now].flag_)%p;
else rc->flag_=tree[now].flag_,rc->if_=true;
tree[now].if_=false;
}
if(tree[now].flag)
{
lc->flag=(lc->flag+tree[now].flag)%p;
rc->flag=(rc->flag+tree[now].flag)%p;
lc->dis=(lc->dis+((lc->r-lc->l+)%p)*tree[now].flag)%p;
rc->dis=(rc->dis+((rc->r-rc->l+)%p)*tree[now].flag)%p;
tree[now].flag=;
}
}
if(l>tree[now].mid) tree_do(now<<|,l,r);
else if(r<=tree[now].mid) tree_do(now<<,l,r);
else
{
tree_do(now<<,l,tree[now].mid);
tree_do(now<<|,tree[now].mid+,r);
}
tree[now].dis=(tree[now<<].dis+tree[now<<|].dis)%p;
} int main()
{
in(n),in(m),in(p);LL l,r;
tree_build(,,n);
while(m--)
{
in(type),in(l),in(r);
if(type==||type==) in(x),tree_do(,l,r);
else
{
ans=;
tree_do(,l,r);
printf("%lld\n",ans);
}
}
return ;
}

最新文章

  1. git操作---查询
  2. IO:File类(java.io.File)
  3. Linux网络编程-SIGPIPE信号导致的程序退出问题
  4. [转]Hibernate不能自动建表解决办法及Hibernate不同数据库的连接及SQL方言
  5. mongo db 分享 ppt
  6. [译]如何在Unity编辑器中添加你自己的工具
  7. SSH电力项目
  8. TCP为什么需要3次握手与4次挥手
  9. IT职位分析
  10. 适用于SQl数据的Sql语句
  11. 【01背包】洛谷P1282多米诺骨牌
  12. DRBD的主备安装配置
  13. java上传excel到后台解析入库
  14. Java Memory Management
  15. JavaScript的组成 | DOM/BOM
  16. Mysql中Left Join Right Join Inner Join where条件的比较
  17. ruby楼层排序问题
  18. ACM数论之旅14---抽屉原理,鸽巢原理,球盒原理(叫法不一又有什么关系呢╮(╯▽╰)╭)
  19. 无聊,纯css写了个评分鼠标移入的效果
  20. 查找网页元素对应的js代码

热门文章

  1. (68)zabbix windows性能计数器使用详解
  2. 在VUE中,关于CKEditor使用
  3. 转载:将画布(canvas)图像保存成本地图片的方法
  4. 《linux设备驱动开发详解》笔记——10中断与时钟
  5. Python学习笔记:os模块和sys模块
  6. leetcode-8-pointer
  7. IDEA常用快捷键(不全)
  8. city Engine 建模
  9. HDU - 1496 Equations (hash)
  10. 面试(手打手写,待更新loading...)