老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。
输入格式:
第一行两个整数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)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。
输出格式:
对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。
输入样例#1:
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
输出样例#1:
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 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: Ahoi 2009
调了一个半小时,调不出来
不调了、、
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<cmath>
5 #include<algorithm>
6 #define lli long long
7 using namespace std;
8 const int MAXN=500001;
9 lli n,m,mod,ans;
10 void read(lli & n)
11 {
12 char c='+';lli x=0;bool flag=0;
13 while(c<'0'||c>'9')
14 {c=getchar();if(c=='-')flag=1;}
15 while(c>='0'&&c<='9')
16 {x=x*10+(c-48),c=getchar();}
17 flag==1?n=-x:n=x;
18 }
19 struct node
20 {
21 lli l,r,w,k,fc,fj;
22 }tree[MAXN*4];
23 void pushdown(lli k,lli ll,lli rr,lli mid)
24 {
25 tree[k<<1].w*=tree[k].fc%mod;
26 tree[k<<1|1].w*=tree[k].fc%mod;
27 tree[k<<1].w=(tree[k<<1].w+tree[k].fj*(mid-ll+1))%mod;
28 tree[k<<1|1].w=(tree[k<<1|1].w+tree[k].fj*(rr-mid))%mod;
29
30 tree[k<<1].fc%=mod;tree[k<<1|1].fc%=mod;
31 tree[k<<1].fj%=mod;tree[k<<1|1].fj%=mod;
32 tree[k<<1].w%=mod;tree[k<<1|1].w%=mod;
33
34 tree[k<<1].fc*=tree[k].fc%mod;tree[k<<1|1].fc*=tree[k].fc%mod;
35 tree[k<<1].fj*=tree[k].fc%mod;tree[k<<1|1].fj*=tree[k].fc%mod;
36 tree[k<<1].fj=(tree[k<<1].fj+tree[k].fj)%mod;
37 tree[k<<1|1].fj=(tree[k<<1|1].fj+tree[k].fj)%mod;
38
39
40 tree[k].fc=1;
41 tree[k].fj=0;
42
43
44 tree[k<<1].fc%=mod;tree[k<<1|1].fc%=mod;
45 tree[k<<1].fj%=mod;tree[k<<1|1].fj%=mod;
46 tree[k<<1].w%=mod;tree[k<<1|1].w%=mod;
47 }
48 void update(lli k)
49 {
50 tree[k].w=(tree[k<<1].w+tree[k<<1|1].w)%mod;
51 }
52 void build_tree(lli ll,lli rr,lli k)
53 {
54 tree[k].l=ll;tree[k].r=rr;tree[k].k=k;
55 tree[k].fc=1;tree[k].fj=0;
56 if(tree[k].l==tree[k].r)
57 {
58 read(tree[k].w);
59 tree[k].w%=mod;
60 return ;
61 }
62 lli mid=(ll+rr)>>1;
63 build_tree(ll,mid,k<<1);
64 build_tree(mid+1,rr,k<<1|1);
65 update(k);
66 }
67 void interval_mul(lli k,lli ll,lli rr,lli v)
68 {
69 if(ll>tree[k].r||rr<tree[k].l)
70 return ;
71 if(tree[k].l>=ll&&tree[k].r<=rr)
72 {
73 tree[k].w*=v%mod;
74 tree[k].fc*=v%mod;
75 tree[k].fj*=v%mod;
76 return ;
77 }
78 lli mid=(tree[k].l+tree[k].r)>>1;
79 pushdown(k,tree[k].l,tree[k].r,mid);
80 if(ll<=mid)
81 interval_mul(k<<1,ll,rr,v);
82 if(rr>mid)
83 interval_mul(k<<1|1,ll,rr,v);
84 update(k);
85 }
86 void interval_add(lli k,lli ll,lli rr,lli v)
87 {
88 if(ll>tree[k].r||rr<tree[k].l)
89 return ;
90 if(tree[k].l>=ll&&tree[k].r<=rr)
91 {
92 tree[k].w=(tree[k].w+v*(tree[k].r-tree[k].l+1))%mod;
93 //tree[k].fc*=v%mod;
94 tree[k].fj=(tree[k].fj+v)%mod;
95 return ;
96 }
97 lli mid=(tree[k].l+tree[k].r)>>1;
98 pushdown(k,tree[k].l,tree[k].r,mid);
99 if(ll<=mid)
100 interval_add(k<<1,ll,rr,v);
101 if(rr>mid)
102 interval_add(k<<1|1,ll,rr,v);
103 update(k);
104
105 }
106 void interval_ask(lli k,lli ll,lli rr)
107 {
108 if(ll>tree[k].r||rr<tree[k].l)
109 return ;
110 if(tree[k].l>=ll&&tree[k].r<=rr)
111 {
112 ans=(ans+tree[k].w)%mod;
113 return ;
114 }
115 lli mid=(tree[k].l+tree[k].r)>>1;
116 pushdown(k,tree[k].l,tree[k].r,mid);
117 if(ll<=mid)
118 interval_ask(k<<1,ll,rr);
119 if(rr>mid)
120 interval_ask(k<<1|1,ll,rr);
121 update(k);
122 }
123 int main()
124 {
125 read(n);read(mod);
126 build_tree(1,n,1);
127 read(m);
128 for(lli i=1;i<=m;i++)
129 {
130 lli how,x,y,c;
131 read(how);
132 if(how==1)
133 {
134 read(x);read(y);read(c);
135 interval_mul(1,x,y,c%mod);//乘
136 }
137 else if(how==2)
138 {
139 read(x);read(y);read(c);
140 interval_add(1,x,y,c%mod);// 加
141 }
142 else if(how==3)
143 {
144 ans=0;
145 read(x);read(y);
146 interval_ask(1,x,y);
147 printf("%lld\n",ans);
148 }
149 }
150 return 0;
151 }
1 #include<iostream>
2 #include<cstdio>
3 #define lli long long int
4 #define re register
5 #define LL long long
6 #define M 500000
7 using namespace std;
8 void read(lli & n)
9 {
10 char c='+';lli x=0;bool flag=0;
11 while(c<'0'||c>'9')
12 {c=getchar();if(c=='-')flag=1;}
13 while(c>='0'&&c<='9')
14 {x=x*10+(c-48),c=getchar();}
15 flag==1?n=-x:n=x;
16 }
17 LL mogician,a[M/2+1];
18 int n;
19 struct Tree{
20 LL sum,add,mult;
21 }tr[M+1];
22 inline void build(int k,int l,int r){
23 tr[k].mult=1;
24 if(l==r){
25 tr[k].sum=a[l];
26 return ;
27 }
28 int mid=(l+r)>>1;
29 build(k<<1,l,mid);
30 build(k<<1|1,mid+1,r);
31 tr[k].sum=(tr[k<<1].sum+tr[k<<1|1].sum)%mogician;
32 }
33 inline void Work_Out(int k,int l,int r,LL mu,LL ad){
34 tr[k].add=(tr[k].add*mu+ad)%mogician;
35 tr[k].mult=(tr[k].mult*mu)%mogician;
36 tr[k].sum=(tr[k].sum*mu+(r-l+1)*ad)%mogician;
37 }
38 inline void Push_Down(int k,int l,int r){
39 if(tr[k].add==0&&tr[k].mult==1)
40 return ;
41 int mid=(l+r)>>1;
42 Work_Out(k<<1,l,mid,tr[k].mult,tr[k].add);
43 Work_Out(k<<1|1,mid+1,r,tr[k].mult,tr[k].add);
44 tr[k].add=0;
45 tr[k].mult=1;
46 }
47 inline void Lazy_Tag(int k,int l,int r,int x,int y,LL mu,LL ad){
48 if(x<=l&&r<=y){
49 Work_Out(k,l,r,mu,ad);
50 return ;
51 }
52 Push_Down(k,l,r);
53 int mid=(l+r)>>1;
54 if(x<=mid)
55 Lazy_Tag(k<<1,l,mid,x,y,mu,ad);
56 if(mid<y)
57 Lazy_Tag(k<<1|1,mid+1,r,x,y,mu,ad);
58 tr[k].sum=(tr[k<<1].sum+tr[k<<1|1].sum)%mogician;
59 }
60 inline LL Q(int k,int l,int r,int x,int y){
61 if(x<=l&&r<=y)
62 return tr[k].sum%mogician;
63 Push_Down(k,l,r);
64 int mid=(l+r)>>1;
65 return ((x<=mid?Q(k<<1,l,mid,x,y)%mogician:0)+(mid<y?Q(k<<1|1,mid+1,r,x,y)%mogician:0))%mogician;
66 }
67 int m,d,x,y;
68 LL k;
69 int main(){
70
71 scanf("%lld%lld",&n,&mogician);
72 for(re int i=1;i<=n;i++){
73 scanf("%lld",&a[i]);
74 a[i]%=mogician;
75 }
76 build(1,1,n);
77 scanf("%d",&m);
78 for(re int i=1;i<=m;i++){
79 scanf("%d%d%d",&d,&x,&y);
80 if(d==3)
81 printf("%lld\n",Q(1,1,n,x,y));
82 else{
83 scanf("%lld",&k);
84 k%=mogician;
85 d==1?Lazy_Tag(1,1,n,x,y,k,0):Lazy_Tag(1,1,n,x,y,1,k);
86 }
87 }
88 return 0;
89 }