维护什么
bzoj1798维护序列
原理lazy标记
一个是乘,一个是加
加不影响乘
乘要让加的标记也乘
开longlong
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define ll long long
inline ll read()
{
ll num=0;
char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch<='9'&&ch>='0')
{
num*=10;
num+=ch-'0';
ch=getchar();
}
return num;
}
struct seg{
ll sum;
ll add;
ll mul;
ll left,right;
}tree[400025];
ll n,p,OPE,ADD,MUL,L,R;
ll m;
void build(int x,int l,int r){
if(l==r) {
tree[x].sum=read()%p;
tree[x].add=0;
tree[x].mul=1;
tree[x].left=l;
tree[x].right=r;
return;
}
int mid=(l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
tree[x].sum=(tree[x<<1].sum+tree[x<<1|1].sum)%p;
tree[x].left=l;
tree[x].right=r;
tree[x].mul=1;
tree[x].add=0;
return ;
}
void push_down(int num)//大概的意思就是把标记打下去
{
if(tree[num].add==0&&tree[num].mul==1) return ;
tree[num<<1].add=(tree[num].mul*tree[num<<1].add+tree[num].add)%p;
tree[num<<1].mul=(tree[num].mul*tree[num<<1].mul)%p;
tree[num<<1|1].add=(tree[num].mul*tree[num<<1|1].add+tree[num].add)%p;
tree[num<<1|1].mul=(tree[num].mul*tree[num<<1|1].mul)%p;
tree[num<<1].sum=(tree[num].mul*tree[num<<1].sum+(tree[num<<1].right-tree[num<<1].left+1)*tree[num].add)%p;
tree[num<<1|1].sum=(tree[num].mul*tree[num<<1|1].sum+(tree[num<<1|1].right-tree[num<<1|1].left+1)*tree[num].add)%p;
tree[num].add=0;
tree[num].mul=1;
}
void add(int x,int l,int r,int num)//注意延迟标记的下放问题
{
if(l>tree[num].right||r<tree[num].left) return ;
if(l<=tree[num].left&&r>=tree[num].right) {
tree[num].add=(tree[num].add+x)%p;
tree[num].sum=(tree[num].sum+x*(tree[num].right-tree[num].left+1))%p;
return ;
}
push_down(num);