AHOI 2009

老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。

有长为 nn 的数列,不妨设为 a1​,a2​,⋯,an​。有如下三种操作形式:

  • 把数列中的一段数全部乘一个值;
  • 把数列中的一段数全部加一个值;
  • 询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模 P 的值。

输入格式

第一行两个整数 n 和 P;

第二行含有 n 个非负整数,从左到右依次为 a1​,a2​,⋯,an​;

第三行有一个整数 M,表示操作总数;

从第四行开始每行描述一个操作,输入的操作有以下三种形式:

  • 操作 1:1 t g c,表示把所有满足t≤i≤g 的 a_iai​ 改为ai​×c;
  • 操作 2:2 t g c,表示把所有满足t≤i≤g 的 a_iai​ 改为 ai​+c;
  • 操作 3:3 t g,询问所有满足 t≤i≤g 的 a_iai​ 的和模 P 的值。

同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。

输出格式

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

样例

样例输入

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

样例输出

2
35
8

样例说明

初始时数列为{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≤t≤g≤n,0≤c,ai​≤10^9,1≤P≤10^9。

测试数据规模如下表所示:n,m<=1e5

______________________________________________________________

线段树维护两个懒惰标记,增加值和乘积
______________________________________________________________
  1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const int maxn=1e5+10;
5 ll n,m,p;
6 ll sum[maxn<<2],dels[maxn<<2],delp[maxn<<2];
7 ll a[maxn];
8 void down(ll cur,ll l,ll r)
9 {
10 if(delp[cur]!=1)
11 {
12 sum[cur<<1]=(sum[cur<<1]*delp[cur])%p;
13 sum[cur<<1|1]=(sum[cur<<1|1]*delp[cur])%p;
14 delp[cur<<1]=(delp[cur<<1]*delp[cur])%p;
15 delp[cur<<1|1]=(delp[cur<<1|1]*delp[cur])%p;
16 dels[cur<<1]=(dels[cur<<1]*delp[cur])%p;
17 dels[cur<<1|1]=(dels[cur<<1|1]*delp[cur])%p;
18 delp[cur]=1;
19 }
20 if(dels[cur])
21 {
22 ll mid=(l+r)>>1;
23 sum[cur<<1]=(sum[cur<<1]+dels[cur]*(mid-l+1))%p;
24 sum[cur<<1|1]=(sum[cur<<1|1]+dels[cur]*(r-mid))%p;
25 dels[cur<<1]=(dels[cur<<1]+dels[cur])%p;
26 dels[cur<<1|1]=(dels[cur<<1|1]+dels[cur])%p;
27 dels[cur]=0;
28 }
29 }
30 void build(ll cur,ll l,ll r)
31 {
32 if(l==r)
33 {
34 sum[cur]=a[l]%p;
35 delp[cur]=1;
36 return ;
37 }
38 ll mid=(l+r)>>1;
39 build(cur<<1,l,mid);
40 build(cur<<1|1,mid+1,r);
41 sum[cur]=(sum[cur<<1]+sum[cur<<1|1])%p;
42 delp[cur]=1;
43 }
44 void change1(ll cur,ll l,ll r,ll ql,ll qr,ll x)
45 {
46 if(ql<=l && r<=qr)
47 {
48 sum[cur]=(sum[cur]*x)%p;
49 delp[cur]=(delp[cur]*x)%p;
50 dels[cur]=(dels[cur]*x)%p;
51 return ;
52 }
53 if(dels[cur] || delp[cur]!=1)down(cur,l,r);
54 ll mid=(l+r)>>1;
55 if(ql<=mid)change1(cur<<1,l,mid,ql,qr,x);
56 if(mid<qr)change1(cur<<1|1,mid+1,r,ql,qr,x);
57 sum[cur]=(sum[cur<<1]+sum[cur<<1|1])%p;
58 }
59 void change2(ll cur,ll l,ll r,ll ql,ll qr,ll x)
60 {
61 if(ql<=l && r<=qr)
62 {
63 sum[cur]=(sum[cur]+x*(r-l+1))%p;
64 dels[cur]=dels[cur]+x>=p?dels[cur]+x-p:dels[cur]+x;
65 return ;
66 }
67 if(dels[cur] || delp[cur]!=1)down(cur,l,r);
68 ll mid=(l+r)>>1;
69 if(ql<=mid)change2(cur<<1,l,mid,ql,qr,x);
70 if(mid<qr)change2(cur<<1|1,mid+1,r,ql,qr,x);
71 sum[cur]=(sum[cur<<1]+sum[cur<<1|1])%p;
72 }
73 ll query(ll cur,ll l,ll r,ll ql,ll qr)
74 {
75 if(ql<=l && r<=qr)return sum[cur];
76 if(dels[cur] || delp[cur]!=1)down(cur,l,r);
77 ll ans=0;
78 ll mid=(l+r)>>1;
79 if(ql<=mid)ans+=query(cur<<1,l,mid,ql,qr);
80 if(mid<qr)ans+=query(cur<<1|1,mid+1,r,ql,qr);
81 return ans%p;
82 }
83 int main()
84 {
85 scanf("%lld%lld",&n,&p);
86 for(int i=1;i<=n;++i)scanf("%lld",a+i);
87 build(1,1,n);
88 scanf("%lld",&m);
89 while(m--)
90 {
91 ll op,l,r,x;
92 scanf("%lld",&op);
93 if(op==1)
94 {
95 scanf("%lld%lld%lld",&l,&r,&x);
96 x%=p;
97 change1(1,1,n,l,r,x);
98 }
99 else if(op==2)
100 {
101 scanf("%lld%lld%lld",&l,&r,&x);x%=p;
102 change2(1,1,n,l,r,x);
103 }
104 else
105 {
106 scanf("%lld%lld",&l,&r);
107 cout<<query(1,1,n,l,r)%p<<endl;
108 }
109 }
110 return 0;
111 }

LOJ10129的更多相关文章

随机推荐

  1. Fragment学习

    利用Fragment可以动态的加载页面,减少Activity的数量. 便于开发 类似与html中FragmentSet一样 嵌套在一起,使每个页面为独立的 代码如下: package com.exam ...

  2. golang语法笔记

    开始微服务,那就先温习下golang语法吧; golang变量类型 1. 整形 Go %b    表示为二进制 %c    该值对应的unicode码值 %d    表示为十进制 %o    表示为八 ...

  3. [Skill] git下载助手

    缘由 某些时候需要下载git项目中的某个独立的文件或者文件夹下的内容,克隆全部速度过于慢 搜索下发现有开源的实现,特此记录下 方案 国内不便于fq 源码 服务地址 国外原作者 源码 服务地址 使用方法 ...

  4. Spring 抽象的缓存包 spring-cache

    项目实战 用户信息查询接口中,使用@Cacheable注解  绑定相关信息接口中,使用@CachePut更新用户信息到缓存 更新用户信息接口中,使用@CacheEvict删除缓存信息 使用步骤 添加依 ...

  5. windows环境搭建

    GO语言环境配置: 安装GOlang,添加到环境变量path 默认会创建环境变量GOPATH,其中存放代码和编译后的工程文件等,用户可以根据个人需要,在别的路径下创建gopath,并添加到环境变量中. ...

  6. Docker Java 镜像基础(四)

    基于官方提供的centos 7.2.1511 基础镜像构建JDK 和tomcat 镜像,先构建JDK镜像,然后在基于JDK镜像构建tomcat镜像 构建 centos:latest 基础镜像: # 下 ...

  7. 在 Azure 上执行一些简单的 python 工作

    1. 公司禁用了 python 我的主业是桌面开发,偶尔也需要搞搞数据和算法.最近在用 python 处理一些工作,正搞得热火朝天,突然 python 就不能用了,一查记录原来是 IT 管理员禁止我使 ...

  8. VBA实现相同行合并

    帮人捣鼓了个VBA代码用来实现多行合并,具体需求为:列2/列3/列4 相同的情况下,则对应的行合并为一行,且列1用空格隔开,列5则相加: (对大多数办公室职员,VBA还算是提高效率的一个利器吧) 最终 ...

  9. linux之curl工具

    curl是一个利用URL语法在命令行下工作的文件传输工具,作用是发出网络请求,然后获取数据:它支持文件的上传和下载:支持多种通信协议. 一.查看网页源码 直接在 curl 命令后加上网址,默认会发送 ...

  10. (十九)hashlib模块

    hashlib模块用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法 注意:md5和sha25 ...