1009 [AHOI2009]SEQ 维护序列SEQ 区间加 区间乘
//-------------------------代码---------------------------- #define int ll const int N = 1e5+10; int n,m,p; int a[N]; struct node{ int l,r,s,la1,la2; } tr[N<<2]; void push_up(int u) { tr[u].s = (tr[ul].s + tr[ur].s)% p; } void push_down(int u) { if(tr[u].l==tr[u].r)return ; if(tr[u].la1==0&&tr[u].la2==1)return ; int x=tr[u].la1;tr[u].la1=0; int y=tr[u].la2;tr[u].la2=1; //更新子节点 tr[ul].la1=(tr[ul].la1*y)%p;tr[ul].la2=(tr[ul].la2*y)%p; tr[ul].s=(tr[ul].s*y)%p; tr[ul].la1=(tr[ul].la1+x)%p;tr[ul].s=(tr[ul].s+tr_len(ul)*x)%p; tr[ur].la1=(tr[ur].la1*y)%p;tr[ur].la2=(tr[ur].la2*y)%p; tr[ur].s=(tr[ur].s*y)%p; tr[ur].la1=(tr[ur].la1+x)%p;tr[ur].s=(tr[ur].s+tr_len(ur)*x)%p; } void build(int u,int l,int r) { if(l == r) { tr[u] = {l,r,a[l]%p,0,1}; rt; } int mid = l + r >> 1; build(u<<1,l,mid);build(u<<1|1,mid+1,r); tr[u] = {l,r,0,0,1}; push_up(u); } int query(int u,int l,int r) { if(l <= tr[u].l && tr[u].r <= r) return tr[u].s; if(l > tr[u].r || r < tr[u].l) return 0; push_down(u); return (query(ul,l,r) + query(ur,l,r)) % p; } void modify1(int u,int l,int r,int c) { if(l <= tr[u].l && tr[u].r <= r) { tr[u].la1=(tr[u].la1+c)%p; tr[u].s=(tr[u].s+tr_len(u)*c)%p; rt; } push_down(u); int mid = tr[u].l + tr[u].r >> 1; if(l <= mid) modify1(u<<1,l,r,c); if(mid < r ) modify1(ur,l,r,c); push_up(u); } void modify2(int u,int l,int r,int c) { if(l <= tr[u].l && tr[u].r <= r) { tr[u].s = tr[u].s * c % p; tr[u].la2 *= c;tr[u].la1 *= c; tr[u].la2 %= p;tr[u].la1 %= p; rt; } push_down(u); int mid = tr[u].l + tr[u].r >> 1; if(l <= mid) modify2(u<<1,l,r,c); if(mid < r ) modify2(ur,l,r,c); push_up(u); } void solve() { // cin>>n>>m; cin>>n>>p; fo(i,1,n) cin>>a[i]; cin>>m; build(1,1,N-3); while(m -- ) { int op,t,g,c; cin>>op>>t>>g; if(op == 2) { cin>>c; modify1(1,t,g,c); } else if(op == 1) { cin>>c; modify2(1,t,g,c); } else if(op == 3) { cout<<query(1,t,g)% p <<endl; } } } void main_init() {} signed main(){ AC();clapping();TLE; cout<<fixed<<setprecision(12); main_init(); // while(cin>>n,n) // while(cin>>n>>m,n,m) // int t;cin>>t;while(t -- ) solve(); // {solve(); } return 0; } /*样例区 */ //------------------------------------------------------------
链接:https://ac.nowcoder.com/acm/contest/26896/1009
来源:牛客网
题目描述
老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为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,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。
备注:
对于全部的测试点,保证 0≤p,ai,c≤109,1≤t≤g≤n。0 \leq p, a_i, c \leq 10^9 ,1 \leq t \leq g \leq n。0≤p,ai,c≤109,1≤t≤g≤n。