Seq 维护序列seq

Time Limit: 30 Sec  Memory Limit: 64 MB
Submit: 4184  Solved: 1518
[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

HINT

【样例说明】

初始时数列为(1,2,3,4,5,6,7)。
经过第1次操作后,数列为(1,10,15,20,25,6,7)。
对第2次操作,和为10+15+20=45,模43的结果是2。
经过第3次操作后,数列为(1,10,24,29,34,15,16}
对第4次操作,和为1+10+24=35,模43的结果是35。
对第5次操作,和为29+34+15+16=94,模43的结果是8。

测试数据规模如下表所示

数据编号 1 2 3 4 5 6 7 8 9 10
N= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000
M= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000

题解:给两个操作,操作1,把l,r数字乘以c,操作2:把l,r数字都加上c;
直接开两个标记去存储,样例过了,但是无限wa;
我有几点没考虑完全:
1:对于第一个操作,每次标记应该都是乘以c;而我弄成加了,因为假设第一次乘以5,第二次再乘以5,就是25
了;
2:对于第二种操作,没有考虑到第一种操作可以影响第二种操作,如果执行第一种操作,里面的元素编程5倍了,此时标记2也应当乘以相应倍数;加上5+2,5乘以5了,2也应当乘以5;
总结:考虑问题还是不太全面,不能完全驾驭题目;
代码:
 extern "C++"{
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cassert>
#include<cstdlib>
using namespace std;
typedef long long LL;
typedef unsigned u;
typedef unsigned long long ull;
#define mem(x,y) memset(x,y,sizeof(x))
void SI(double &x){scanf("%lf",&x);}
void SI(int &x){scanf("%d",&x);}
void SI(LL &x){scanf("%lld",&x);}
void SI(u &x){scanf("%u",&x);}
void SI(ull &x){scanf("%llu",&x);}
void SI(char *s){scanf("%s",s);} void PI(int x){printf("%d",x);}
void PI(double x){printf("%lf",x);}
void PI(LL x){printf("%lld",x);}
void PI(u x){printf("%u",x);}
void PI(ull x){printf("%llu",x);}
void PI(char *s){printf("%s",s);} #define NL puts("");
#define ll root<<1
#define rr root<<1|1
#define lson ll,l,mid
#define rson rr,mid+1,r
const int INF=0x3f3f3f3f;
const int MAXN=;
LL tree[MAXN << ];
LL lazy[MAXN << ];
LL lazy2[MAXN << ];
LL P;
}
void pushup(int root){
tree[root] = tree[ll] + tree[rr];
tree[root] %= P;
}
void pushdown(int root,int x){
if(lazy[root] != ){
lazy[ll] *= lazy[root];
lazy[rr] *= lazy[root]; lazy2[ll] *= lazy[root];
lazy2[rr] *= lazy[root];
// tree[ll]=lazy[root]*(mid-l+1);
// tree[rr]=lazy[root]*(r-mid);
tree[ll] *= lazy[root];
tree[rr] *= lazy[root]; lazy[ll] %= P;
lazy[rr] %= P;
tree[ll] %= P;
tree[rr] %= P;
lazy2[ll] %= P;
lazy2[rr] %= P; lazy[root] = ;
}
if(lazy2[root]){
lazy2[ll] += lazy2[root];
lazy2[rr] += lazy2[root]; lazy2[ll] %= P;
lazy2[rr] %= P; tree[ll] += lazy2[root] * (x - (x >> ) ) % P;
tree[rr] += lazy2[root] * (x >> ) % P; tree[ll] %= P;
tree[rr] %= P; lazy2[root] = ;
}
}
void build(int root,int l,int r){
int mid = (l + r) >> ;
lazy[root] = ;
lazy2[root] = ;
if(l == r){
SI(tree[root]);
return ;
}
build(lson);
build(rson);
pushup(root);
}
void update(int root,int l,int r,int L,int R,int C,int t){
if(l >= L && r <= R){
if(t == ){
lazy[root] *= C;
tree[root] *= C;
lazy2[root] *= C;
lazy2[root] %= P;
lazy[root] %= P;
tree[root] %= P;
}
else if(t == ){
lazy2[root] += C % P;
tree[root] += C * (r - l +) % P;
lazy2[root] %= P;
tree[root] %= P;
}
return ;
}
int mid = (l + r) >> ;
pushdown(root,r - l + );
if(mid >= L)
update(lson,L,R,C,t);
if(mid < R)
update(rson,L,R,C,t);
pushup(root);
}
LL query(int root,int l,int r,int L,int R){
int mid = (l + r) >> ;
if(l >= L && r <= R){
return tree[root];
}
pushdown(root,r - l + );
LL ans = ;
if(mid >= L)
ans += query(lson,L,R);
if(mid < R)
ans += query(rson,L,R);
return ans;
}
int main(){
// assert(true);
int N,M;
while(~scanf("%d%lld",&N,&P)){
build(,,N);
SI(M);
int a,l,r,c;
while(M--){
SI(a);SI(l);SI(r);
if(a == ){
printf("%lld\n",query(,,N,l,r) % P);
}
else{
SI(c);
update(,,N,l,r,c,a);
}
}
}
return ;
}

bzoj 维护序列seq(双标记线段树)的更多相关文章

  1. bzoj 1798 [Ahoi2009]Seq 维护序列seq(线段树+传标)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1798 [题意] 给定一个序列,要求提供区间乘/加,以及区间求和的操作 [思路] 线段树 ...

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

    http://www.lydsy.com/JudgeOnline/problem.php?id=1798 之前写了个快速乘..........................20多s...... 还好 ...

  3. BZOJ 1798: [Ahoi2009]Seq 维护序列seq (线段树乘法加法的混合操作)

     题目:点击打开链接 大意:一个数组.三个操作.第一种是区间[a,b]每一个数乘乘,另外一种是区间[a,b]每一个数加c,第三种是查询[a,b]区间的和并对p取摸. 两种操作就不能简单的仅仅往下传 ...

  4. _bzoj1798 [Ahoi2009]Seq 维护序列seq【线段树 lazy tag】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 注意,应保证当前节点维护的值是正确的,lazy tag只是一个下传标记,在下传时应即时 ...

  5. AHOI 2009 (BZOJ1798)维护序列 seq (线段树好题?)

    我是不会说这个题很坑的.. 改了一晚上... // by SiriusRen #include <cstdio> #define N 150000 #define LSON l,mid,l ...

  6. P2023 [AHOI2009]维护序列 题解(线段树)

    题目链接 P2023 [AHOI2009]维护序列 解题思路 线段树板子.不难,但是...有坑.坑有多深?一页\(WA\). 由于乘法可能乘\(k=0\),我这种做法可能会使结果产生负数.于是就有了这 ...

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

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

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

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

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

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

随机推荐

  1. UVA_Cubic Eight-Puzzle UVA 1604

    Let's play a puzzle using eight cubes placed on a 3 x 3 board leaving one empty square.Faces of cube ...

  2. java Socket 使用注意

    Socket s = new Socket(ia, port); BufferedOutputStream bufOut = new BufferedOutputStream(s.getOutputS ...

  3. 利用FreeMarker静态化网页

    1.介绍-FreeMarker是什么 模板引擎:一种基于模板的.用来生成输出文本的通用工具 基于Java的开发包和类库 2.介绍-FreeMarker能做什么 MVC框架中的View层组件 Html页 ...

  4. LINQ 之四 (SkipWhile和TakeWhile)

    看到书上的例子很正常,于是,我写了个不正常一点的. 书上的是这样的 class Program { static void Main(string[] args) { ,,,,,,,,}; ); fo ...

  5. ADO.net基础学习总结(二)

    将连接字符串放入配置文件中 1.添加一个“应用程序配置文件:app.config” <?xml version="1.0" encoding="utf-8" ...

  6. RFC端口号定义

    RFC关于计算机端口号定义 http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers. ...

  7. c#中的peek()方法

    peek()方法用来判断文件是否读取完成,如果完成的话,就会有一个返回值 - 1 所以可以用streamreader的对象sr调用peek()方法来判断文件流是否读取完成 ) { Console.Wr ...

  8. EntityFramework sum嵌套

    一个查询中 用到了 sum , 可是返回结果的小数有很多位 , 都不准确了..类似js中的小数运算一样...不太熟悉C#,不知道这问题是因为double的关系 , 还是因为代码写的问题 , 通过 sq ...

  9. VC++深入详解读书笔记-第七章对话框

    1.在MFC中,所有的控件类都是由CWnd类派生来的,因此,控件实际上也是窗口. 2. 3.对话框的种类 模态对话框 模态对话框是指当其显示时,程序会暂时执行,直到关闭这个模态对话框后,才能继续执行程 ...

  10. logfile提示stale错误解决方法

    产生该错误的原因解释如下: Explanation: ============ A stale redo log file is one that Oracle believes might be i ...