可惜没如果=_=
时光的河入海流

1798: [Ahoi2009]Seq 维护序列seq

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

Source

水题没话说qwq
 1 #include "bits/stdc++.h"
 2 #define lson rt<<1,l,m
 3 #define rson rt<<1|1,m+1,r
 4 using namespace std;
 5 typedef long long LL;
 6 const int MAX=100005;
 7 int n,m;
 8 LL sum[MAX*6],la1[MAX*6],la2[MAX*6],mod;
 9 void PushDown(int rt,int l,int r){
10     if (l==r || (la2[rt]==0 && la1[rt]==1)) return;
11     int m=(l+r)>>1;
12     sum[rt<<1]=(sum[rt<<1]*la1[rt]+la2[rt]*(m-l+1))%mod;
13     sum[rt<<1|1]=(sum[rt<<1|1]*la1[rt]+la2[rt]*(r-m))%mod;
14     
15     la2[rt<<1]=(la2[rt<<1]*la1[rt]+la2[rt])%mod;
16     la2[rt<<1|1]=(la2[rt<<1|1]*la1[rt]+la2[rt])%mod;
17     la2[rt]=0;
18     
19     la1[rt<<1]=la1[rt<<1]*la1[rt]%mod;la1[rt<<1|1]=la1[rt<<1|1]*la1[rt]%mod;
20     la1[rt]=1;
21 }
22 void PushUp(int rt){
23     sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%mod;
24 }
25 void build(int rt,int l,int r){
26     la1[rt]=1;la2[rt]=0;
27     if (l==r){
28         scanf("%lld",&sum[rt]);
29         return;
30     }
31     int m=(l+r)>>1;
32     build(lson);
33     build(rson);
34     PushUp(rt);
35 }
36 void Update1(int x,int y,int z,int rt,int l,int r){
37     if (x<=l && r<=y){
38         PushDown(rt,l,r);
39         la1[rt]=z;
40         sum[rt]=sum[rt]*(LL)z%mod;
41         return;
42     }
43     int m=(l+r)>>1;
44     PushDown(rt,l,r);
45     if (x<=m) Update1(x,y,z,lson);
46     if (y>m) Update1(x,y,z,rson);
47     PushUp(rt);
48 }
49 void Update2(int x,int y,int z,int rt,int l,int r){
50     if (x<=l && r<=y){
51         la2[rt]+=z;
52         sum[rt]=(sum[rt]+(LL)z*(r-l+1))%mod;
53         return;
54     }
55     int m=(l+r)>>1;
56     PushDown(rt,l,r);
57     if (x<=m) Update2(x,y,z,lson);
58     if (y>m) Update2(x,y,z,rson);
59     PushUp(rt);
60 }
61 LL search(int x,int y,int rt,int l,int r){
62     if (x<=l && r<=y){
63         return sum[rt];
64     }
65     LL an=0;
66     int m=(l+r)>>1;
67     PushDown(rt,l,r);
68     if (x<=m) an=(an+search(x,y,lson))%mod;
69     if (y>m) an=(an+search(x,y,rson))%mod;
70     return an;
71 }
72 int main(){
73     freopen ("seq.in","r",stdin);freopen ("seq.out","w",stdout);
74     int i,j;
75     int x,y,z,w;
76     scanf("%d%d",&n,&mod);
77     build(1,1,n);
78     scanf("%d",&m);
79     for (i=1;i<=m;i++){
80         scanf("%d",&w);
81         if (w==1){
82             scanf("%d%d%d",&x,&y,&z);
83             Update1(x,y,z,1,1,n);
84         }
85         if (w==2){
86             scanf("%d%d%d",&x,&y,&z);
87             Update2(x,y,z,1,1,n);
88         }
89         if (w==3){
90             scanf("%d%d",&x,&y);
91             printf("%lld\n",search(x,y,1,1,n));
92         }
93     }
94     return 0;
95 }

 

posted on 2017-10-24 23:27  珍珠鸟  阅读(196)  评论(0编辑  收藏  举报