树状数组就是个辣鸡
不扯了
先给链接
#include<iostream>
using namespace std;
struct node
{
long long val;
long long tag;
}tree[10000000];
long long in[10000000];
void build(long long root,long long start,long long end)
{
tree[root].tag=0;
if(start==end)
{
tree[root].val=in[start];
return ;
}
long long mid=(start+end)/2;
build(root*2,start,mid);
build(root*2+1,mid+1,end);
tree[root].val=tree[root*2].val+tree[root*2+1].val;
return ;
}
void push(long long root,long long start,long long end,long long mid)
{
if(tree[root].tag)
{
tree[root*2].tag+=tree[root].tag;
tree[root*2+1].tag+=tree[root].tag;
tree[root*2].val+=tree[root].tag*(mid-start+1);
tree[root*2+1].val+=tree[root].tag*(end-mid);
tree[root].tag=0;
}
return ;
}
void update(long long root,long long nstart,long long nend,long long ustart,long long uend,long long add) // cymbal
{
if(nstart>uend||nend<ustart)
{
return ;
}
if(nstart>=ustart&&nend<=uend)
{
tree[root].tag+=add;
tree[root].val+=add*(nend-nstart+1);
return ;
}
long long mid=(nstart+nend)/2;
push(root,nstart,nend,mid);
update(root*2,nstart,mid,ustart,uend,add);
update(root*2+1,mid+1,nend,ustart,uend,add);
tree[root].val=tree[root*2].val+tree[root*2+1].val;
return ;
}
long long check(long long root,long long nstart,long long nend,long long ustart,long long uend)
{
if(nstart>uend||nend<ustart)
{
return 0;
}
if(nstart>=ustart&&nend<=uend)
{
return tree[root].val;
}
long long mid=(nstart+nend)/2;
push(root,nstart,nend,mid);
long long cym=check(root*2,nstart,mid,ustart,uend)
+check(root*2+1,mid+1,nend,ustart,uend);
return cym;
}
int main()
{
cin.sync_with_stdio(false);
long long l,m;
cin>>l>>m;
for(long long i=1;i<=l;i++)
cin>>in[i];
long long a,b;
long long f,k;
build(1,1,l);
for(long long i=1;i<=m;i++)
{
cin>>f>>a>>b;
if(f==1)
{
cin>>k;
update(1,1,l,a,b,k);
}
if(f==2)
cout<<check(1,1,l,a,b)<<endl;
}
return 0;
}
因为是区间加,在push懒标记时和要加上区间长度*懒标记
如果时区间大小的话就不用le。要根据实际情况设计push函数
在看一道区间乘和加的题
这道题告诉了我们如何处理两种运算的关系
(如果不知到的话,看看洛谷题解就行了,洛谷还是很好的网站,最起码,它不baoza
#include<iostream>
using namespace std;
struct node
{
long long val;
long long tag1;//*
long long tag2;//+
node(){val=0;tag1=1;tag2=0;}
};
node tree[400000];
long long in[100010];
long long n,m,p;
void build(long long root,long long left,long long right)
{
if(left==right)
{
tree[root].val=in[left]%p;
return ;
}
long long mid=(left+right)/2;
build(root*2,left,mid);
build(root*2+1,mid+1,right);
tree[root].val=tree[root*2].val+tree[root*2+1].val;
tree[root].val%=p;
return ;
}
void push_down(long long root,long long left,long long right,long long mid)
{
tree[root*2].val=((tree[root*2].val*tree[root].tag1)%p+tree[root].tag2*(mid-left+1))%p;
tree[root*2].tag1=(tree[root*2].tag1*tree[root].tag1)%p;
tree[root*2].tag2=(tree[root*2].tag2*tree[root].tag1+tree[root].tag2)%p;
tree[root*2+1].val=((tree[root*2+1].val*tree[root].tag1)%p+tree[root].tag2*(right-mid))%p;
tree[root*2+1].tag1=(tree[root*2+1].tag1*tree[root].tag1)%p;
tree[root*2+1].tag2=(tree[root*2+1].tag2*tree[root].tag1+tree[root].tag2)%p;
tree[root].tag1=1;
tree[root].tag2=0;
}
void updata1(long long root,long long nleft,long long nright,long long aleft,long long aright,long long value)
{
if(nleft>aright||nright<aleft)
return ;
if(nleft>=aleft&&nright<=aright)
{
tree[root].val=(tree[root].val*value)%p;
tree[root].tag1=(tree[root].tag1*value)%p;
tree[root].tag2=(tree[root].tag2*value)%p;
return ;
}
long long mid=(nleft+nright)/2;
push_down(root,nleft,nright,mid);
updata1(root*2,nleft,mid,aleft,aright,value);
updata1(root*2+1,mid+1,nright,aleft,aright,value);
tree[root].val=(tree[root*2].val+tree[root*2+1].val)%p;
return ;
}
void updata2(long long root,long long nleft,long long nright,long long aleft,long long aright,long long value)
{
if(nleft>aright||nright<aleft)
return ;
if(nleft>=aleft&&nright<=aright)
{
tree[root].val=(tree[root].val+value*(nright-nleft+1))%p;
tree[root].tag2=(tree[root].tag2+value)%p;
return ;
}
long long mid=(nleft+nright)/2;
push_down(root,nleft,nright,mid);
updata2(root*2,nleft,mid,aleft,aright,value);
updata2(root*2+1,mid+1,nright,aleft,aright,value);
tree[root].val=(tree[root*2].val+tree[root*2+1].val)%p;
return ;
}
long long check(long long root,long long nleft,long long nright,long long aleft,long long aright)
{
if(nleft>aright||nright<aleft)
return 0;
if(nleft>=aleft&&nright<=aright)
return tree[root].val;
long long mid=(nleft+nright)/2;
push_down(root,nleft,nright,mid);
long long ans=(
check(root*2,nleft,mid,aleft,aright)+
check(root*2+1,mid+1,nright,aleft,aright)
)%p;
return ans;
}
int main()
{
cin.sync_with_stdio(false);
cin>>n>>m>>p;
for(long long i=1;i<=n;i++)
cin>>in[i];
build(1,1,n);
long long a,b,c,d;
for(long long i=1;i<=m;i++)
{
cin>>a;
switch(a)
{
case 1:
cin>>b>>c>>d;
updata1(1,1,n,b,c,d);
break;
case 2:
cin>>b>>c>>d;
updata2(1,1,n,b,c,d);
break;
case 3:
cin>>b>>c;
cout<<check(1,1,n,b,c)<<endl;
break;
}
}
return 0;
}
同时也要注意数据范围,我就是载在了上面。