1798: [Ahoi2009]Seq 维护序列seq

Time Limit: 30 Sec  Memory Limit: 64 MB
Submit: 8058  Solved: 2964
[Submit][Status][Discuss]

Description

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

Input

第一行两个整数N和P(1≤P≤1000000000)。第二行含有N个非负整数,从左到右依次为a1,a2,…,aN, (0≤ai≤1000000000,1≤i≤N)。第三行有一个整数M,表示操作总数。从第四行开始每行描述一个操作,输入的操作有以下三种形式: 操作1:“1 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai×c (1≤t≤g≤N,0≤c≤1000000000)。 操作2:“2 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai+c (1≤t≤g≤N,0≤c≤1000000000)。 操作3:“3 t g”(不含双引号)。询问所有满足t≤i≤g的ai的和模P的值 (1≤t≤g≤N)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。

Output

对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。

Sample Input

7 43
1 2 3 4 5 6 7
5
1 2 5 5
3 2 4
2 3 7 9
3 1 3
3 4 7

Sample Output

2
35
8
 
从中午写题开始一直写到晚上转钟,中间写了无数次bug和被自己手抖写错了一个地方
找bug真的是难受,以后这样就直接重新写吧
题意:线段树的查询、区间修改、sum和的操作
题解:从某大佬的专题学习了线段树在结构体里面的写法,在结构体里面创建树的话,就可以直接调用和查询
   板子题了,用sum数组来存这颗树,每次插入操作对树上的每一段区间/节点都进行一次update
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 8e5+;
long long mod;
long long n,m;
struct segtree{
#define lc(x) (x*2)
#define rc(x) (x*2+1)
long long l[maxn],r[maxn];
long long sumi[maxn],mul[maxn],add[maxn];
void build(int x,int L,int R){
//数组从1开始
l[x]=L;
r[x]=R;
add[x]=;
mul[x]=;
if(L==R){
//区间节点
cin>>sumi[x];
return;
}
int mid=(L+R)/;
build(lc(x),L,mid);
build(rc(x),mid+,R);
update(x);
}
void update(int x){
sumi[x]=(sumi[lc(x)]+sumi[rc(x)])%mod;
}
void push(int x){
mul[lc(x)]=(mul[lc(x)]*mul[x])%mod;
mul[rc(x)]=(mul[rc(x)]*mul[x])%mod;
add[lc(x)]=(add[lc(x)]*mul[x]+add[x])%mod;
add[rc(x)]=(add[rc(x)]*mul[x]+add[x])%mod;
sumi[lc(x)]=(sumi[lc(x)]*mul[x]+
add[x]*(r[lc(x)]-l[lc(x)]+))%mod;
sumi[rc(x)]=(sumi[rc(x)]*mul[x]+
add[x]*(r[rc(x)]-l[rc(x)]+))%mod;
add[x]=;
mul[x]=;
}
void ADD(int x,int L,int R,long long v){
push(x);
if(R<l[x]||L>r[x]) return; //查询区间不在范围内
if(L<=l[x]&&r[x]<=R){
sumi[x]=(sumi[x]+v*(r[x]-l[x]+))%mod;
add[x]=(add[x]+v)%mod;
return;
}
ADD(lc(x),L,R,v);
ADD(rc(x),L,R,v);
update(x);
}
void MUL(int x,int L,int R,long long v){
push(x);
if(R<l[x]||L>r[x]) return;
if(L<=l[x]&&r[x]<=R){
sumi[x]=(sumi[x]*v)%mod;
add[x]=(add[x]*v)%mod;
mul[x]=(mul[x]*v)%mod;
return;
}
MUL(lc(x),L,R,v);
MUL(rc(x),L,R,v);
update(x);
}
long long Qsum(int x,int L,int R){
push(x);
if(l[x]>R||r[x]<L) return ;
if(L<=l[x]&&r[x]<=R) return sumi[x];
return (Qsum(lc(x),L,R)+Qsum(rc(x),L,R))%mod;
}
}seg; int main(){
cin>>n>>mod;
seg.build(,,n);
cin>>m;
for(long long i= ,op,l,r;i<=m;i++){
cin>>op>>l>>r;
if(op==) {
cout<<seg.Qsum(,l,r)<<endl;
}
else{
long long v;
cin>>v;
if(op==) seg.MUL(,l,r,v);
else seg.ADD(,l,r,v);
}
}
return ;
}

BZOJ1798 维护序列seq的更多相关文章

  1. 【双标记线段树】bzoj1798维护序列seq

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

  2. BZOJ1798: [Ahoi2009]Seq 维护序列seq[线段树]

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 5504  Solved: 1937[Submit ...

  3. bzoj 维护序列seq(双标记线段树)

    Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 4184  Solved: 1518[Submit][Status][Discus ...

  4. BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )

    线段树.. 打个 mul , add 的标记就好了.. 这个速度好像还挺快的...( 相比我其他代码 = = ) 好像是#35.. ---------------------------------- ...

  5. 1798: [Ahoi2009]Seq 维护序列seq

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 2930  Solved: 1087[Submit ...

  6. bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树 ,多重标记下放)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 7773  Solved: 2792[Submit ...

  7. bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeO ...

  8. Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...

  9. BZOJ1798[Ahoi2009]Seq 维护序列seq 题解

    题目大意: 有长为N的数列,有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值. ...

随机推荐

  1. CAS解扰小结

    1.每个ts数据包由:1.包头 2.包数据 包头有个字段 PID ,该字段指示包数据的类型.比如说: PID 为 0x0000 包数据的类型就是 PAT表 PID 为 0x0001 包数据的类型就是 ...

  2. 2-Linux C语言指针与内存-学习笔记

    Linux C语言指针与内存 前面我们对于: c语言的基本用法 makeFile文件的使用 main函数的详解 标准输入输出流以及错误流管道 工具与原理 指针与内存都是c语言中的要点与难点 指针 数组 ...

  3. R语言学习笔记(十五):获取文件和目录信息

    file.info() 参数是表示文件名称的字符串向量,函数会给出每个文件的大小.创建时间.是否为目录等信息. > file.info("z.txt") size isdir ...

  4. HDU暑假多校第八场G-Card Game

    一.题意 给出N个卡牌,卡牌的正反两面具有两个数字,取值范围为[1,2*n],给出若干个默认正面向上的卡牌,求最小反转多少张卡牌可以使得,每张卡牌朝上的面上都有一个不同的数字,同时满足最小反转次数的反 ...

  5. 教你Zbrush 4R7怎样创建Z球

    随着CG行业的迅猛发展,就业门槛大幅度提高,对于从业人员要求就是要“又快又好”,作为一个模型师,常会碰到一天或两天完成一个全身角色的考题,而且还需要角度摆出造型,以前做这个的话,可能比较难,现在有了Z ...

  6. 【转载】[Elasticsearch]ES入门

    传送门:http://www.cnblogs.com/xing901022 ES即简单又复杂,你可以快速的实现全文检索,又需要了解复杂的REST API.本篇就通过一些简单的搜索命令,帮助你理解ES的 ...

  7. 用gradle编译任意结构的Android项目

    ## 需求 * 继续用`Eclipse`项目的结构,但是使用`gradle`编译,或者说任意的项目结构进行编译. ## 解决方案 1. Android studio的项目结构 1. Android S ...

  8. mybatis if标签比较字符串

    项目中需要在mybatis后台比较字符串 因为mybatis映射文件使用的是ognl表达式,所以不能使用 <if test="type == '0'"> 解决: < ...

  9. 【功能笔记】Ubuntu查看系统资源占用(内存,cpu和进程) {转载}

    转载自http://bluexp29.blog.163.com/blog/static/33858148201071534450856/ linux真是太强大了. 查看ubuntu的资源占用的命令为$ ...

  10. 2016弱校联盟十一专场10.3 We don't wanna work!

    能把 not working now 写成 not working hard now 还查一晚上也是没谁了 我的做法是维护两个set 分别是前20% 和后80% #include<iostrea ...