[Luogu 2023] AHOI2009 维护序列

[Luogu 2023] AHOI2009 维护序列

<题目链接>


恕我冒昧这和线段树模板二有个琴梨区别?

#include <cstdio>
int n,m;
long long p;
class SegmentTree
{
    private:
        struct Node
        {
			int left,right;
            long long v,mul,add;
            Node *c[2];
            Node(int l,int r):left(l),right(r),mul(1LL),add(0LL)
            {
				if(l==r)
				{
					scanf("%lld",&v);
					return;
				}
				int mid=l+r>>1;
				c[0]=new Node(l,mid);
				c[1]=new Node(mid+1,r);
				PushUp();
            }
            ~Node(void)
            {
                if(c[0]!=nullptr)
                    delete c[0];
                if(c[1]!=nullptr)
                    delete c[1];
            }
            long long Size(void)
            {
				return (long long)(right-left+1);
            }
            long long Value(bool p)
            {
                return c[p]!=nullptr ? c[p]->v : 0;
            }
            void Modify(long long _mul,long long _add)
            {
                v=(v*_mul+Size()*_add)%p;
                mul=mul*_mul%p;
                add=(add*_mul+_add)%p;
            }
            void MulModify(long long k)
            {
                v=v*k%p;
                mul=mul*k%p;
                add=add*k%p;
            }
            void AddModify(long long k)
            {
                v=(v+Size()*k)%p;
                add=(add+k)%p;
            }
            void PushUp(void)
            {
                v=(Value(0)+Value(1))%p;
            }
            void PushDown(void)
            {
                if(c[0]!=nullptr)
                    c[0]->Modify(mul,add);
                if(c[1]!=nullptr)
                    c[1]->Modify(mul,add);
                mul=1,add=0;
            }
			void Mul(int l,int r,long long k)
			{
				if(l==left && r==right)
				{
					MulModify(k);
					return;
				}
				PushDown();
				int mid=left+right>>1;
				if(r<=mid)
					c[0]->Mul(l,r,k);
				else if(l>mid)
					c[1]->Mul(l,r,k);
				else
				{
					c[0]->Mul(l,mid,k);
					c[1]->Mul(mid+1,r,k);
				}
				PushUp();
			}
			void Add(int l,int r,long long k)
			{
				if(l==left && r==right)
				{
					AddModify(k);
					return;
				}
				PushDown();
				int mid=left+right>>1;
				if(r<=mid)
					c[0]->Add(l,r,k);
				else if(l>mid)
					c[1]->Add(l,r,k);
				else
				{
					c[0]->Add(l,mid,k);
					c[1]->Add(mid+1,r,k);
				}
				PushUp();
			}
			long long Sum(int l,int r)
			{
				if(l==left && r==right)
					return v;
				PushDown();
				int mid=left+right>>1;
				if(r<=mid)
					return c[0]->Sum(l,r);
				else if(l>mid)
					return c[1]->Sum(l,r);
				else
					return (c[0]->Sum(l,mid)+c[1]->Sum(mid+1,r))%p;
			}
        }*root;
    public:
		SegmentTree(int n):root(new Node(1,n)){}
        ~SegmentTree(void)
        {
			delete root;
        }
        void Mul(int l,int r)
        {
            long long k;
            scanf("%lld",&k);
			root->Mul(l,r,k);
        }
        void Add(int l,int r)
        {
            long long k;
            scanf("%lld",&k);
			root->Add(l,r,k);
        }
        void Sum(int l,int r)
        {
            printf("%lld\n",root->Sum(l,r));
        }
};
int main(int argc,char** argv)
{
	scanf("%d %lld",&n,&p);
    SegmentTree *T=new SegmentTree(n);
	scanf("%d",&m);
    for(int i=1,opt,x,y;i<=m;++i)
    {
        scanf("%d %d %d",&opt,&x,&y);
        switch(opt)
        {
            case 1:
                T->Mul(x,y);
                break;
            case 2:
                T->Add(x,y);
                break;
            case 3:
                T->Sum(x,y);
                break;
        }
    }
    delete T;
    return 0;
}
posted @ 2018-06-19 11:38  Capella  阅读(168)  评论(2编辑  收藏  举报

谢谢光临