老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。
有长为NN的数列,不妨设为a1,a2,…,aNa1,a2,…,aN。有如下三种操作形式:
(1)把数列中的一段数全部乘一个值;
(2)把数列中的一段数全部加一个值;
(3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模PP的值。
PS:本数据为纯随机数据,由菜god友情提供
第一行两个整数NN和P(1≤P≤1000000000)P(1≤P≤1000000000)。
第二行含有NN个非负整数,从左到右依次为a1,a2,…,aNa1,a2,…,aN, (0≤ai≤1000000000,1≤i≤N)(0≤ai≤1000000000,1≤i≤N)。
第三行有一个整数MM,表示操作总数。
从第四行开始每行描述一个操作,输入的操作有以下三种形式:
操作11:“1 t g c1 t g c”(不含双引号)。表示把所有满足t≤i≤gt≤i≤g的aiai改为ai×c(1≤t≤g≤N,0≤c≤1000000000)ai×c(1≤t≤g≤N,0≤c≤1000000000)。
操作22:“2 t g c2 t g c”(不含双引号)。表示把所有满足t≤i≤gt≤i≤g的aiai改为ai+c(1≤t≤g≤N,0≤c≤1000000000)ai+c(1≤t≤g≤N,0≤c≤1000000000)。
操作33:“3 t g3 t g”(不含双引号)。询问所有满足t≤i≤gt≤i≤g的aiai的和模PP的值 (1≤t≤g≤N)(1≤t≤g≤N)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。
对每个操作33,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。
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,2,3,4,5,6,7)。
经过第11次操作后,数列为(1,10,15,20,25,6,7)(1,10,15,20,25,6,7)。
对第22次操作,和为10+15+20=4510+15+20=45,模4343的结果是22。
经过第33次操作后,数列为(1,10,24,29,34,15,16)(1,10,24,29,34,15,16)
对第44次操作,和为1+10+24=351+10+24=35,模4343的结果是3535。
对第55次操作,和为29+34+15+16=9429+34+15+16=94,模4343的结果是88。
测试数据规模如下表所示
数据编号 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
Ahoi2009
#include <stdio.h> #define re register typedef long long LL; inline void read(LL &x) { x=0;char c=getchar(); for(; ‘0‘>c || c>‘9‘; c=getchar()); for(; ‘0‘<=c && c<=‘9‘; c=getchar()) x=(x<<1)+(x<<3)+(c^48); } struct node { LL sum; LL mul,add; }; LL P; LL a[100001]; node *s=new node[400004]; inline void build(LL id,LL l,LL r) { s[id].mul=1; s[id].add=0; if(l==r) { s[id].sum=a[l]; return ; } LL mid=(l+r)>>1; build(id<<1,l,mid); build(id<<1|1,mid+1,r); s[id].sum=(s[id<<1].sum+s[id<<1|1].sum)%P; } inline void pushdown(LL id,LL l,LL r) { LL mid=(l+r)>>1; s[id<<1].sum=((s[id<<1].sum*s[id].mul)+((mid-l+1)*s[id].add))%P; s[id<<1|1].sum=((s[id<<1|1].sum*s[id].mul)+((r-mid)*s[id].add))%P; s[id<<1].mul=(s[id<<1].mul*s[id].mul)%P; s[id<<1|1].mul=(s[id<<1|1].mul*s[id].mul)%P; s[id<<1].add=(s[id<<1].add*s[id].mul+s[id].add)%P; s[id<<1|1].add=(s[id<<1|1].add*s[id].mul+s[id].add)%P; s[id].add=0; s[id].mul=1; } inline void _mul(LL id,LL l,LL r,LL L,LL R,LL w) { if(L<=l && r<=R) { s[id].mul=(s[id].mul*w)%P; s[id].add=(s[id].add*w)%P; s[id].sum=(s[id].sum*w)%P; return ; } pushdown(id,l,r); LL mid=(l+r)>>1; if(L<=mid) _mul(id<<1,l,mid,L,R,w); if(R>mid) _mul(id<<1|1,mid+1,r,L,R,w); s[id].sum=(s[id<<1].sum+s[id<<1|1].sum)%P; } inline void _add(LL id,LL l,LL r,LL L,LL R,LL w) { if(L<=l && r<=R) { s[id].add=(s[id].add+w)%P; s[id].sum=(s[id].sum+w*(r-l+1))%P; return ; } pushdown(id,l,r); LL mid=(l+r)>>1; if(L<=mid) _add(id<<1,l,mid,L,R,w); if(R>mid) _add(id<<1|1,mid+1,r,L,R,w); s[id].sum=(s[id<<1].sum+s[id<<1|1].sum)%P; } inline LL search(LL id,LL l,LL r,LL L,LL R) { if(R<l || r<L) return 0; if(L<=l && r<=R) return s[id].sum; pushdown(id,l,r); LL mid=(l+r)>>1; return (search(id<<1,l,mid,L,R)+search(id<<1|1,mid+1,r,L,R))%P; } int main() { LL N; read(N),read(P); for(re LL i=1; i<=N; ++i) read(a[i]); build(1,1,N); LL M; read(M); for(re LL i=1; i<=M; ++i) { LL Q,T,G; read(Q),read(T),read(G); switch (Q) { case 1 :{ LL C; read(C); _mul(1,1,N,T,G,C); break; } case 2 :{ LL C; read(C); _add(1,1,N,T,G,C); break; } default :{ printf("%lld\n",search(1,1,N,T,G)); break; } } } delete[] s; return 0; }
Ojbk
原文:https://www.cnblogs.com/Retr67/p/9534576.html