HDU ACM 4578 Transformation->段树-间隔的变化

HDU ACM 4578 Transformation->段树-间隔的变化

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

分析:复杂的经营分部树。

只有一个查询操作,这是要求[l,r]的数量之间p钍总和。并不是所有的查询所有节点,会议TLE。最好的是查询部件[a。b]。所有这个区间值我们是平等的,即能返回(b-a+1)*val 的值。区间内全部值都同样的情况的区间。对于置初值和加乘操作。分两种情况:1、当为置初值操作。直接覆盖区间就可以。并把标记的加乘操作赋为初始值。2、当为加乘操作时。先推断当前区间段是否为同样的值,是的话直接加乘,维护这个同样的值就可以。假设不同样,看区间是否已有加乘标记,把这个加乘标记一直传递下去。直到遇见那个区间段区间全部值同样时停止。最后把这个加乘赋给最開始的区间段。简单的说就是,覆盖操作可直接维护,不是覆盖操作的话。区间仅仅能保留一个加乘操作。

#include<iostream>
using namespace std;

#define lz t<<1,l,mid           //左区间
#define rz (t<<1)|1,mid+1,r     //右区间
#define N 100005
#define MOD 10007
__int64 add[N<<2],mul[N<<2],chan[N<<2],sum[N<<2];

void Build(int t,int l,int r)  //建立线段树
{
	int mid;

	mul[t]=1;
	add[t]=sum[t]=0;
	chan[t]=0;
	if(l==r)
	{
		chan[t]=1;           //叶节点设为1。方便询问的查询
		return ;
	}
	mid=(l+r)>>1;
	Build(lz);
	Build(rz);
}

void PushDown(int t,int l,int r)   //标记下传
{
	int mid;

	if(l==r) return ;
	mid=(l+r)>>1;
	if(chan[t])      //set标记下传
	{
		add[t<<1]=0,mul[t<<1]=1;
		add[(t<<1)|1]=0,mul[(t<<1)|1]=1;
		chan[t<<1]=chan[(t<<1)|1]=1;
		sum[t<<1]=sum[(t<<1)|1]=sum[t];
		chan[t]=0;
	}
	else 
	{
		if(add[t])  //加标记下传
		{
	    	if(chan[t<<1]) sum[t<<1]=(sum[t<<1]+add[t])%MOD; //左子树有set标记
    		else
			{
	    		PushDown(lz);   //下传
	    		add[t<<1]=(add[t<<1]+add[t])%MOD;
			}
	     	if(chan[(t<<1)|1]) sum[(t<<1)|1]=(sum[(t<<1)|1]+add[t])%MOD; //左子树有set标记
	    	else
			{
	    		PushDown(rz);   //下传
	    		add[(t<<1)|1]=(add[(t<<1)|1]+add[t])%MOD;
			}
	    	add[t]=0;
		}
		if(mul[t]>1) //乘标记下传
		{
    		if(chan[t<<1]) sum[t<<1]=(sum[t<<1]*mul[t])%MOD; //左子树有set标记
	     	else
			{
		    	PushDown(lz);   //下传
		    	mul[t<<1]=(mul[t<<1]*mul[t])%MOD;
			}
	    	if(chan[(t<<1)|1]) sum[(t<<1)|1]=(sum[(t<<1)|1]*mul[t])%MOD; //左子树有set标记
	    	else
			{
	     		PushDown(rz);   //下传
	    		mul[(t<<1)|1]=(mul[(t<<1)|1]*mul[t])%MOD;
			}
	    	mul[t]=1;
		}
	}
}

void Update(int t,int l,int r,int ul,int ur,int c,int op)
{
	int mid;

	if(l>=ul && ur>=r) //边界
	{
		if(op==3)
			chan[t]=1,mul[t]=1,add[t]=0,sum[t]=c;
		else if(chan[t])
		{
			if(op==1) sum[t]=(sum[t]+c)%MOD;
			else sum[t]=(sum[t]*c)%MOD;
		}
		else
		{
			PushDown(t,l,r);  //下传
			if(op==1) add[t]=(add[t]+c)%MOD;
			else mul[t]=(mul[t]*c)%MOD;
		}
		return ;
	}
	PushDown(t,l,r);
	mid=(l+r)>>1;
	if(ur<=mid) Update(lz,ul,ur,c,op);
	else if(ul>mid) Update(rz,ul,ur,c,op);
	else
	{
		Update(lz,ul,mid,c,op);
		Update(rz,mid+1,ur,c,op);
	}
}

__int64 Query(int t,int l,int r,int ul,int ur,int p)
{
	int mid,i;
	__int64 ans,tp,t1,t2;

	if(ul<=l && r<=ur)
		if(chan[t])
		{
			ans=1;
			tp=sum[t];
			for(i=1;i<=p;i++) ans=(ans*tp)%MOD;
			return (r-l+1)*ans%MOD;              //由于区间的每一个部分都是同样的
		}
	PushDown(t,l,r);  //下传标记
	mid=(l+r)>>1;
	if(ur<=mid) return Query(lz,ul,ur,p);
	else if(ul>mid) return Query(rz,ul,ur,p);
	else
	{
		t1=Query(lz,ul,mid,p);
		t2=Query(rz,mid+1,ur,p);
		return (t1+t2)%MOD;
	}
}

int main()
{
	int n,m,i,l,r,c,op;

	while(scanf("%d%d",&n,&m)==2 && n+m)
	{
		Build(1,1,n);    //1为根节点
		for(i=1;i<=m;i++)
		{
			scanf("%d%d%d%d",&op,&l,&r,&c);
			if(op<=3) Update(1,1,n,l,r,c,op);
			else
				printf("%I64d\n",Query(1,1,n,l,r,c)%MOD);
		}
	}
	return 0;
}

版权声明:本文博主原创文章。博客,未经同意不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116783.html原文链接:https://javaforall.net

(0)
上一篇 2022年1月15日 下午5:00
下一篇 2022年1月15日 下午5:00


相关推荐

  • 3d工具收集_3d图表走势综合版

    3d工具收集_3d图表走势综合版Poser是Metacreations公司推出的一款三维动物、人体造型和三维人体动画制作的极品软件。用过Poser2与Poser3的朋友一定能感受到Poser的人体设计和动画制作是那么的轻松自如,制作出的作品又是那么生动。而今Poser更能为你的三维人体造型增添发型、衣服、饰品等装饰。让你的设计与创意轻松展现。Mixamo:在线3D动漫角…

    2022年8月23日
    9
  • 腾讯混元OCR大模型,本地部署,实测

    腾讯混元OCR大模型,本地部署,实测

    2026年3月12日
    2
  • codetemp-2: CObject::AssertValid()

    codetemp-2: CObject::AssertValid()原型:[virtual]voidCObject::AssertValid()const//说明:该成员函数只能对成员变量做”引用型”操作,不能做”加工型”操作{ASSERT(this!=NULL);}MSDN:Whenyouwriteyourownclass,youshouldoverridetheAssertValidfunc…

    2022年7月15日
    16
  • ASP也做工作流

    ASP也做工作流

    2021年8月7日
    65
  • javascript 换行符[通俗易懂]

    javascript 换行符[通俗易懂] 在JS的字符串里对[TAB]的表述是 /x09  你可以做这样的测试: alert(“/x41”); //看看得到是什么?? 是字母A(41是十六进制的ASCII码值)  我喜欢用 /x0f 这类的做分隔符, [TAB]键用户还是有可能输入的, 但 /x0f 就绝对不可能输入  var s = “A/x0fB/x0fC/x0f

    2022年5月10日
    46
  • Java面试题目,Java中级面试题及答案整理(1)

    Java面试题目,Java中级面试题及答案整理(1)(5)GlobalSession:这个只在portal应用中有用,给每一个globalhttpsession新建一个Bean实例。5、Spring事务传播行为所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有

    2022年8月31日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号