区间加和区间乘

1.区间加

输入\(n,m\),分别表示有\(n\)个数,m个步骤。

下面1个数x,表示原高度,然后m+2行操作。

操作1:给出\(L,R,y\) ,表示在\([L,R]\)区间内,每个数加上y。

操作2:给出\(L,R\),表示询问在\([L,R]\)区间内每个高度之和。

操作1表示为\(1\) \(L\) \(R\) \(x\)

操作2表示为\(2\) \(L\) \(R\)

方案一:将\([L,R]\)区间内,每个数循环加上y。但是复杂度太高。

方案二:将\(a[L]=x+y\)\(a[R+1]-=y\)

然后再用循环\(a[i]=a[i-1]\)

这样复杂度就大大减少啦。

2.区间乘

代码如下,方法与区间加similar:

void cheng(long long l,long long r,long long id,long long tl,long long tr,long long x)
{
    if(tl<=l&&r<=tr)
    {
        ch[id]=((long long)ch[id]*x)%P;
        dx[id]=((long long)dx[id]*x)%P;
        sum[id]=((long long)sum[id]*x)%P;
        return;
    }
    int mid=(l+r)/2;
    if((ch[id]!=1) || dx[id])
    {
        dx[id<<1]=((long long)dx[id<<1]*ch[id]+dx[id])%P;
        ch[id<<1]=((long long)ch[id<<1]*ch[id])%P;
        sum[id<<1]=(((long long)sum[id<<1]*ch[id])%P+(LL)dx[id]*(mid-l+1)%P)%P;

        ch[id<<1|1]=((long long)ch[id<<1|1]*ch[id])%P;dx[id<<1|1]=((LL)dx[id<<1|1]*ch[id]+dx[id])%P;
        sum[id<<1|1]=(((long long)sum[id<<1|1]*ch[id])%P+(LL)dx[id]*(r-mid)%P)%P;

        ch[id]=1;dx[id]=0;
    }

    if(tl<=mid) cheng(l,mid,id*2,tl,tr,x);
    if(tr>=mid+1) cheng(mid+1,r,id*2+1,tl,tr,x);
    sum[id]=(sum[id<<1]+sum[id<<1|1])%P;
    return;
}

\(\texttt{U121358 在火星上}\)

\(\texttt{P1880 [NOI1995]石子合并}\)

\(\texttt{P1437 [P4170 [CQOI2007]涂色}\)

posted @ 2020-08-27 16:48  panjoel  阅读(389)  评论(0)    收藏  举报