1798: [Ahoi2009]Seq 维护序列seq

Time Limit: 30 Sec  Memory Limit: 64 MB

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

  迷醉线段树题。

  这特么明显的线段树裸题,10w的数据,多组询问,支持区间修改和求和。

  所以就是在lazy标记上做文章。

  维护两个lazy标记,一个乘一个加。

  因为要满足运算符优先级,所以乘法必须马上实现在加法上。

  也就是说乘法的时候把加法的lazy也乘一遍。

  所以lazy的乘法操作都是当前节点已经搞完了的。

  那么lazy的下放就是要先乘再加了,不然会乘重复。

  理清楚优先级的限制之后很好做的。(真的吗?)

  反正我感觉乘的lazy就是加的lazy的lazy,除了一些维护答案的地方外... ...

  感觉越说越不清楚,代码糊上。

#include    <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
#include <complex>
#include <stack>
#define ls (x<<1)
#define rs (x<<1|1)
#define LL long long int
#define dob double
using namespace std; const int N = 100010;
int n,P,m,T[N<<2],lazy_A[N<<2],lazy_M[N<<2]; int gi()
{
int x=0,res=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')res*=-1;ch=getchar();}
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*res;
} inline void build(int x,int l,int r){
if(l==r){T[x]=gi();return;}
int mid=(l+r)>>1;
build(ls,l,mid);build(rs,mid+1,r);
T[x]=(T[ls]+T[rs])%P;
lazy_A[x]=0;lazy_M[x]=1;
} inline void down(int x,int l,int r){
int mid=(l+r)>>1;
T[ls]=(1ll*T[ls]*lazy_M[x]+1ll*(mid-l+1)*lazy_A[x])%P;
T[rs]=(1ll*T[rs]*lazy_M[x]+1ll*(r-mid)*lazy_A[x])%P;
lazy_M[ls]=(1ll*lazy_M[ls]*lazy_M[x])%P;
lazy_M[rs]=(1ll*lazy_M[rs]*lazy_M[x])%P;
lazy_A[ls]=(1ll*lazy_A[ls]*lazy_M[x]+1ll*lazy_A[x])%P;
lazy_A[rs]=(1ll*lazy_A[rs]*lazy_M[x]+1ll*lazy_A[x])%P;
lazy_A[x]=0;lazy_M[x]=1;
return;
} inline void Mul(int x,int l,int r,int xl,int xr,int v){
if(l==xl && r==xr){
lazy_A[x]=1ll*lazy_A[x]*v%P;
lazy_M[x]=1ll*lazy_M[x]*v%P;
T[x]=1ll*T[x]*v%P;
return;
}
down(x,l,r);
int mid=(l+r)>>1;
if(xr<=mid)Mul(ls,l,mid,xl,xr,v);
else if(xl>mid)Mul(rs,mid+1,r,xl,xr,v);
else Mul(ls,l,mid,xl,mid,v),Mul(rs,mid+1,r,mid+1,xr,v);
T[x]=(T[ls]+T[rs])%P;
} inline void Add(int x,int l,int r,int xl,int xr,int v){
if(l==xl && r==xr){
lazy_A[x]=(lazy_A[x]+v)%P;
T[x]=(1ll*T[x]+1ll*(r-l+1)*v)%P;
return;
}
down(x,l,r);
int mid=(l+r)>>1;
if(xr<=mid)Add(ls,l,mid,xl,xr,v);
else if(xl>mid)Add(rs,mid+1,r,xl,xr,v);
else Add(ls,l,mid,xl,mid,v),Add(rs,mid+1,r,mid+1,xr,v);
T[x]=(T[ls]+T[rs])%P;
} inline int query(int x,int l,int r,int xl,int xr){
if(l==xl && r==xr)return T[x];
down(x,l,r);
int mid=(l+r)>>1;
if(xr<=mid)return query(ls,l,mid,xl,xr);
else if(xl>mid)return query(rs,mid+1,r,xl,xr);
else return (query(ls,l,mid,xl,mid)+query(rs,mid+1,r,mid+1,xr))%P;
} int main()
{
n=gi();P=gi();
build(1,1,n);
m=gi();
while(m--){
int type=gi();
if(type==1){
int l=gi(),r=gi(),c=gi();
Mul(1,1,n,l,r,c);
}
if(type==2){
int l=gi(),r=gi(),c=gi();
Add(1,1,n,l,r,c);
}
if(type==3){
int l=gi(),r=gi();
printf("%d\n",query(1,1,n,l,r));
}
}
return 0;
}

  

BZOJ1798 AHOI2009 维护数列的更多相关文章

  1. bzoj1798 [Ahoi2009]维护序列

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

  2. 【线段树】Bzoj1798 [AHOI2009] 维护序列

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

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

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

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

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

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

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

  6. [洛谷P2023] [AHOI2009]维护序列

    洛谷题目链接:[AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列 ...

  7. 洛谷 P2023 [AHOI2009]维护序列

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

  8. 洛谷 P2023 [AHOI2009]维护序列 题解

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

  9. 【bzoj1500】 noi2005—维护数列

    http://www.lydsy.com/JudgeOnline/problem.php?id=1500 (题目链接) 题意 要求维护数列,操作有区间删除,区间插入,区间反转,区间修改,区间求和,求最 ...

随机推荐

  1. 解决thymeleaf layout布局不生效

    今天使用thymeleaf layout布局时总是不生效,特此把解决问题的步骤和几个关键点记录下来备忘. 一.检查依赖 1.thymeleaf必备maven依赖: <dependency> ...

  2. Numpy入门 - 数组排序

    本节主要讲解numpy数组的排序方法sort的应用,包括按升序排列和按降序排列. 一.按升序排列 import numpy as np arr = np.array([[3, 1, 2], [6, 4 ...

  3. 【转】如何使用Git上传本地项目到github?(mac版)

    原文链接:http://www.cnblogs.com/lijiayi/p/pushtogithub.html 在此假设你已经在 github 上创建好了一个项目,像这样: 并且你已经完成了自己的项目 ...

  4. WCF、WebAPI、WCFREST、WebService之间的区别和选择

    转载翻译,原文:http://www.dotnet-tricks.com/Tutorial/webapi/JI2X050413-Difference-between-WCF-and-Web-API-a ...

  5. Resin4安装配置

    #Resin4安装配置 # Resin4安装配置 #centos6 #参考http://467754239.blog.51cto.com/4878013/1558435 #yum -y install ...

  6. PostgreSQL启动main函数都干了什么(一)

    DB Version:9.5.3 环境:CentOS7.x 调试工具:GDB source:src/backend/main/main.c 56 /* 57 * Any Postgres server ...

  7. 异常处理第三讲,SEH(结构化异常处理),异常展开问题

    异常处理第三讲,SEH(结构化异常处理),异常展开问题 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) 不知道昨天有木有 ...

  8. 如何使用 Secret?- 每天5分钟玩转 Docker 容器技术(108)

    我们经常要向容器传递敏感信息,最常见的莫过于密码了.比如: docker run -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql 在启动 MySQL 容器时我 ...

  9. js函数的作用域与this指向

    函数的作用域与this指向是js中很重要的一部分,理清这点东西需要个逻辑,看看我的逻辑怎么样... 下面是个提纲,可以直接挑你感兴趣的条目阅读. 函数的定义方式:直接定义(window下,内部定义), ...

  10. ROC和AUC的区别

    ROC是一个曲线,AUC是曲线下面的面积值.   ROC曲线是FPR和TPR的点连成的线. 可以从上面的图看到,横轴是FPR, 纵轴是TPR (TPR = TP / (TP + FN):FPR = F ...