rt
结构体线段树
样例过,其余全Wa
代码中有一些打印,Wa并非打印导致。
#include <iostream>
#include <cstdio>
using namespace std;
struct Tree
{
long long Ls,Rs,Sum,LazyC,LazyJ;
Tree(){Ls = Rs = Sum = LazyJ = 0 ; LazyC = 1;}
void Printf()
{
cout << Ls << " " << Rs << " " << Sum << " The Printf()." << '\n';
}
}A[505005];
long long N,T;
long long Value[100005];
long long MOD;
void UpDate(long long K)
{
A[K].Sum = A[(K<<1)].Sum + A[(K<<1)|1].Sum;
return ;
}
void PushDown(long long K)
{
if(A[K].Ls == A[K].Rs)
{
A[K].LazyC = 1;
A[K].LazyJ = 0;
}
else
{
long long l = (K<<1);
long long r = l|1;
A[l].LazyC = ((A[l].LazyC%MOD)*(A[K].LazyC%MOD)+MOD) % MOD;
A[l].LazyJ = ((A[l].LazyJ%MOD)+(A[K].LazyJ%MOD)+MOD) % MOD;
A[l].Sum = ((A[l].Sum%MOD*(A[K].LazyC%MOD)+MOD) % MOD + ((A[K].LazyJ)*(A[l].Rs-A[l].Ls+1))%MOD) % MOD;
A[r].LazyC = ((A[r].LazyC%MOD)*(A[K].LazyC%MOD)+MOD) % MOD;
A[r].LazyJ = ((A[r].LazyJ%MOD)+(A[K].LazyJ%MOD)+MOD) % MOD;
A[r].Sum = ((A[r].Sum%MOD*(A[K].LazyC%MOD)+MOD) % MOD + ((A[K].LazyJ)*(A[r].Rs-A[r].Ls+1))%MOD) % MOD;
A[K].LazyC = 1;
A[K].LazyJ = 0;
}
return ;
}
void Built(long long K,long long l,long long r)
{
A[K].Ls = l;
A[K].Rs = r;
if(l == r)
{
A[K].Sum = Value[l]%MOD;
return ;
}
long long Mid = (l+r) >> 1;
Built((K<<1),l,Mid);
Built((K<<1)|1,Mid+1,r);
UpDate(K);
return ;
}
void Change(long long K,long long x,long long V)
{
if(A[K].Ls == A[K].Rs)
{
A[K].Sum = V%MOD;
return ;
}
long long Mid = (A[K].Ls+A[K].Rs) >> 1;
if(x <= Mid)
Change((K<<1),x,V);
else
Change((K<<1)|1,x,V);
return ;
}
void ChangeSegmentC(long long K,long long l,long long r,long long V)
{
PushDown(K);
if(A[K].Ls == l && A[K].Rs == r)
{
A[K].Sum = ((A[K].Sum%MOD) * (V%MOD) + MOD) % MOD;
A[K].LazyC = ((A[K].LazyC%MOD) * (V%MOD) + MOD) % MOD;
A[K].Printf();
return ;
}
long long Mid = (A[K].Ls+A[K].Rs) >> 1;
if(r <= Mid)
ChangeSegmentC((K<<1),l,r,V);
else if(l > Mid)
ChangeSegmentC((K<<1)|1,l,r,V);
else
{
ChangeSegmentC((K<<1),l,Mid,V);
ChangeSegmentC((K<<1)|1,Mid+1,r,V);
}
UpDate(K);
return ;
}
void ChangeSegmentJ(long long K,long long l,long long r,long long V)
{
PushDown(K);
if(A[K].Ls == l && A[K].Rs == r)
{
A[K].Sum = ((A[K].Sum%MOD) + (V%MOD)*(r-l+1) + MOD) % MOD;
A[K].LazyJ = ((A[K].LazyJ%MOD) + (V%MOD) + MOD) % MOD;
A[K].Printf();
return ;
}
long long Mid = (A[K].Ls+A[K].Rs) >> 1;
if(r <= Mid)
ChangeSegmentJ((K<<1),l,r,V);
else if(l > Mid)
ChangeSegmentJ((K<<1)|1,l,r,V);
else
{
ChangeSegmentJ((K<<1),l,Mid,V);
ChangeSegmentJ((K<<1)|1,Mid+1,r,V);
}
UpDate(K);
return ;
}
long long Query(long long K,long long l,long long r)
{
PushDown(K);
if(l <= A[K].Ls && A[K].Rs <= r)
return A[K].Sum%MOD;
long long Mid = (A[K].Ls+A[K].Rs) >> 1;
if(r <= Mid)
return Query((K<<1),l,r)%MOD;
else if(l > Mid)
return Query((K<<1)|1,l,r)%MOD;
else
return ((Query((K<<1),l,Mid)%MOD) + (Query((K<<1)|1,Mid+1,r)%MOD) + MOD) % MOD;
}
void Print()
{
for(long long i = 1 ; i<= 2*N+1 ; i++)
if(A[i].Ls == A[i].Rs)
printf("%lld-%lld ",A[i].Sum,A[i].Ls);
puts(" afaf");
}
long long Opt,L,R,Val;
int main()
{
scanf("%lld%lld%lld",&N,&T,&MOD);
for(long long i = 1 ; i<= N ; i++)
scanf("%lld",&Value[i]);
Built(1,1,N);
// Print();
for(long long i = 1 ; i<= T ; i++)
{
scanf("%lld",&Opt);
if(Opt == 1)
{
scanf("%lld%lld%lld",&L,&R,&Val);
ChangeSegmentC(1,L,R,Val);
// Print();
}
else if(Opt == 2)
{
scanf("%lld%lld%lld",&L,&R,&Val);
ChangeSegmentJ(1,L,R,Val);
// Print();
}
else
{
scanf("%lld%lld",&L,&R);
printf("%lld\n",Query(1,L,R));
}
}
return 0;
}