# BZOJ1798题解 Seq维护序列题解 双tag裸线段树

## 1798: [Ahoi2009]Seq 维护序列seq

Time Limit: 30 Sec  Memory Limit: 64 MB
Submit: 5549  Solved: 1951
[Submit][Status][Discuss]

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

## HINT

【样例说明】

N= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000
M= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000

## Source

#include<cstdio>
using namespace std;
#define left l,m,rt<<1
#define right m+1,r,rt<<1|1
#define int_ long long
const int maxn=200010;
int n,m;
int_ mod;
struct NODE{
int_ sum,add,mul;
}res[maxn<<2];
void push_up(int rt){
res[rt].sum=(res[rt<<1].sum+res[rt<<1|1].sum)%mod;
}
void push_down(int rt,int_ len){
if(res[rt].mul!=1||res[rt].add!=0){
res[rt<<1].add = (res[rt<<1].add * res[rt].mul + res[rt].add) % mod ;
res[rt<<1|1].add =(res[rt<<1|1].add * res[rt].mul + res[rt].add) % mod ;
res[rt<<1].sum = (res[rt].mul* res[rt<<1].sum +  res[rt].add * (len-(len>>1))) % mod ;
res[rt<<1|1].sum = (res[rt].mul * res[rt<<1|1].sum+  res[rt].add  * (len>>1) )% mod;

res[rt<<1].mul = (res[rt<<1].mul*res[rt].mul )%mod ;
res[rt<<1|1].mul = (res[rt].mul *res[rt<<1|1].mul) %mod ;
res[rt].mul=1;
res[rt].add=0;

}
}
void build(int l,int r,int rt){
res[rt].mul=1;
if(l==r){
scanf("%lld",&res[rt].sum);
res[rt].sum%=mod;
return ;
}
int m=(l+r)>>1;
build(left);
build(right);
push_up(rt);
}
void update(int op,int_ add,int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
if(op==1){
res[rt].sum=(res[rt].sum+(r-l+1)*add)%mod;
res[rt].add=(res[rt].add+add)%mod;
}
else {
res[rt].sum=(res[rt].sum*add)%mod;
res[rt].add=(res[rt].add*add)%mod;
res[rt].mul=(res[rt].mul*add)%mod;
}
return ;
}
push_down(rt,r-l+1);
int m=(l+r)>>1;
if(L<=m)update(op,add,L,R,left);
if(R>m)update(op,add,L,R,right);
push_up(rt);
}
int_ enquiry(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R)return res[rt].sum;
push_down(rt,r-l+1);
int m=(l+r)>>1;int_ ret=0;
if(L<=m)ret+=enquiry(L,R,left)%mod;
if(R>m)ret+=enquiry(L,R,right)%mod;
return ret;
}
int main(){
scanf("%d %d",&n,&mod);
build(1,n,1);
scanf("%d",&m);
for(int i=1;i<=m;++i){
int x,a,b;int_ c;
scanf("%d",&x);
if(x==1){
scanf("%d %d %lld",&a,&b,&c);
update(2,c,a,b,1,n,1);
}
else if(x==2){
scanf("%d %d %lld",&a,&b,&c);
update(1,c,a,b,1,n,1);
}
else{
scanf("%d %d",&a,&b);
printf("%lld\n",enquiry(a,b,1,n,1)%mod);
}
}
return 0;
}

posted @ 2016-10-15 01:00  Alpar  阅读(124)  评论(0编辑  收藏  举报