线段树的基本操作

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<math.h>
using namespace std;
#define lson rood<<1
#define rson rood<<1|1
#define LL long long
#define INF 0x3f3f3f3f
#define N 100006
LL mod,w[N];
struct node
{
    int l,r;///num表示区间之后要乘
    LL sum,add,num;///sum表示区间和  add表示在区间之后要相加
    int len() {return r-l+1;}///不好看  还是喜欢定义成int len;
    int mid() {return (r+l)/2;}
}a[N<<2];
void q(int rood,int l,int r)
{
    a[rood].l=l;a[rood].r=r;a[rood].num=1;
    a[rood].sum=0;a[rood].add=0;
    if(l==r)
    {
        a[rood].sum=w[l]%mod;
        return ;
    }
    q(lson,l,a[rood].mid());
    q(rson,a[rood].mid()+1,r);
    a[rood].sum=(a[lson].sum+a[rson].sum)%mod;///之和
}
void Q(int rood)
{
    if(a[rood].l!=a[rood].r)///因为我们都是更新在l到r上  所以要往下更新
    {
        a[lson].sum*=a[rood].num;///先将乘的往下运算
        a[lson].add*=a[rood].num;
        a[lson].num*=a[rood].num;

        a[rson].sum*=a[rood].num;
        a[rson].add*=a[rood].num;
        a[rson].num*=a[rood].num;

        a[lson].num%=mod;a[lson].sum%=mod;a[lson].add%=mod;
        a[rson].num%=mod;a[rson].sum%=mod;a[rson].add%=mod;

        a[lson].sum+=a[lson].len()*a[rood].add;///将加的往下运算
        a[lson].add+=a[rood].add;

        a[rson].sum+=a[rson].len()*a[rood].add;
        a[rson].add+=a[rood].add;

        a[lson].sum%=mod;a[lson].add%=mod;
        a[rson].sum%=mod;a[rson].add%=mod;

        a[rood].add=0;a[rood].num=1;///运算结束 ,清空数据
    }
}
void qq(int rood,int l,int r,int e,LL v)
{
    Q(rood);///将本区间的值  往下递推
    if(a[rood].l==l&&a[rood].r==r)
    {
        if(e==1)///乘法
        {
            a[rood].sum*=v;
            a[rood].num*=v;
            a[rood].sum%=mod;
            a[rood].num%=mod;
        }
        else///加法
        {
            a[rood].sum=(a[rood].sum+(r-l+1)*v)%mod;
            a[rood].add+=v;
            a[rood].add%=mod;
        }
        return ;
    }
    
    if(a[rood].mid()>=r)
        qq(lson,l,r,e,v);
    else if(a[rood].mid()<l)
        qq(rson,l,r,e,v);
    else
    {
        qq(lson,l,a[rood].mid(),e,v);
        qq(rson,a[rood].mid()+1,r,e,v);
    }
    a[rood].sum=(a[lson].sum+a[rson].sum)%mod;///运算合并
}
LL qqq(int rood,int l,int r)
{
    if(a[rood].l==l&&a[rood].r==r)
        return a[rood].sum;
    Q(rood);
    if(a[rood].mid()>=r)
        return qqq(lson,l,r);
    else if(a[rood].mid()<l)
        return qqq(rson,l,r);
    else
    {
        LL e=qqq(lson,l,a[rood].mid());
        LL f=qqq(rson,a[rood].mid()+1,r);
        return (e+f)%mod;
    }
}
int main()
{
    int n;
    while(scanf("%d%lld",&n,&mod)!=EOF)
    {
        for(int i=1;i<=n;i++)
            scanf("%lld",&w[i]);
        q(1,1,n);
        int m,e,f,g;
        LL h;
        scanf("%d",&m);
        while(m--)
        {
            scanf("%d%d%d",&e,&f,&g);
            if(e==3)
            {
                printf("%lld\n",qqq(1,f,g)%mod);
                continue;
            }
            scanf("%lld",&h);
            qq(1,f,g,e,h);
        }
    }
    return 0;
}

 

posted on 2017-08-01 09:49  云胡不喜。  阅读(502)  评论(0编辑  收藏  举报