zoukankan      html  css  js  c++  java
  • 「模板」 线段树——区间乘 && 区间加 && 区间求和

    「模板」 线段树——区间乘 && 区间加 && 区间求和

    <题目链接>


    原来的代码太恶心了,重贴一遍。

    #include <cstdio>
    int n,m;
    long long p;
    class SegmentTree
    {
    	private:
    		struct Node
    		{
    			int l,r;
    			long long v,mul,add;
    			Node *c[2];
    			Node(int l,int r):l(l),r(r),mul(1LL),add(0LL)
    			{
    				c[0]=c[1]=nullptr;
    			}
    			~Node(void)
    			{
    				if(c[0]!=nullptr)
    					delete c[0];
    				if(c[1]!=nullptr)
    					delete c[1];
    			}
    			long long Size(void)
    			{
    				return (long long)(r-l+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;
    			}
    		}*rt;
    		void Build(Node* &i,int l,int r)
    		{
    			i=new Node(l,r);
    			if(l==r)
    			{
    				scanf("%lld",&i->v);
    				return;
    			}
    			int mid=l+r>>1;
    			Build(i->c[0],l,mid);
    			Build(i->c[1],mid+1,r);
    			i->PushUp();
    		}
    		void Mul(Node* i,int l,int r,long long k)
    		{
    			if(l==i->l && r==i->r)
    			{
    				i->MulModify(k);
    				return;
    			}
    			i->PushDown();
    			int mid=i->l+i->r>>1;
    			if(r<=mid)
    				Mul(i->c[0],l,r,k);
    			else if(l>mid)
    				Mul(i->c[1],l,r,k);
    			else
    			{
    				Mul(i->c[0],l,mid,k);
    				Mul(i->c[1],mid+1,r,k);
    			}
    			i->PushUp();
    		}
    		void Add(Node* i,int l,int r,long long k)
    		{
    			if(l==i->l && r==i->r)
    			{
    				i->AddModify(k);
    				return;
    			}
    			i->PushDown();
    			int mid=i->l+i->r>>1;
    			if(r<=mid)
    				Add(i->c[0],l,r,k);
    			else if(l>mid)
    				Add(i->c[1],l,r,k);
    			else
    			{
    				Add(i->c[0],l,mid,k);
    				Add(i->c[1],mid+1,r,k);
    			}
    			i->PushUp();
    		}
    		long long Sum(Node* i,int l,int r)
    		{
    			if(l==i->l && r==i->r)
    				return i->v;
    			i->PushDown();
    			int mid=i->l+i->r>>1;
    			if(r<=mid)
    				return Sum(i->c[0],l,r);
    			else if(l>mid)
    				return Sum(i->c[1],l,r);
    			else
    				return (Sum(i->c[0],l,mid)+Sum(i->c[1],mid+1,r))%p;
    		}
    	public:
    		SegmentTree(int n):rt(nullptr)
    		{
    			Build(rt,1,n);
    		}
    		~SegmentTree(void)
    		{
    			delete rt;
    		}
    		void Mul(int l,int r)
    		{
    			long long k;
    			scanf("%lld",&k);
    			Mul(rt,l,r,k);
    		}
    		void Add(int l,int r)
    		{
    			long long k;
    			scanf("%lld",&k);
    			Add(rt,l,r,k);
    		}
    		void Sum(int l,int r)
    		{
    			printf("%lld
    ",Sum(rt,l,r));
    		}
    };
    int main(int argc,char** argv)
    {
    	scanf("%d %d %lld",&n,&m,&p);
    	static SegmentTree *T=new SegmentTree(n);
    	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;
    }
    

    谢谢阅读。

  • 相关阅读:
    使用Junit4进行单元测试
    SourceMonitor的安装及使用
    PMD的安装及使用
    CheckStyle的安装及使用
    FindBugs的安装及使用
    【论文学习】A Study of Equivalent and Stubborn Mutation Operators using Human Analysis of Equivalence
    GitHub
    作业3
    作业2续
    作业2
  • 原文地址:https://www.cnblogs.com/Capella/p/9102625.html
Copyright © 2011-2022 走看看