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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 磁力链接文件服务器,什么是磁力链接(BT、磁力链这些词语是什么意思?)

    磁力链接文件服务器,什么是磁力链接(BT、磁力链这些词语是什么意思?)“知其然知其所以然”。我们经常在下载资料的时候能看到BT、磁力链等词语,百思特网这些词语到底是什么意思呢?下载都会用,但是你了解吗?BT下载传统的下载模式是每个客户端从服务器拷贝文件,跟校园内常用的FTP一样。因为服务器宽带是一定的,所以下载的人越多下载速度会越慢。而现在使用的下载器情况正好相反,使用的人越多文件下载速度越快。这是因为现在的下载器普遍采用类似BT的下载方式。布拉姆科恩发明了BT协议…

    2022年8月10日
    11
  • mcu单片机开发_AVR单片机

    mcu单片机开发_AVR单片机关于单片机(MCU)最强科普

    2022年10月8日
    2
  • 数据库设计中的14个技巧

    数据库设计中的14个技巧

    2021年12月10日
    48
  • 完整的蓝屏错误代码大全详解[通俗易懂]

    完整的蓝屏错误代码大全详解[通俗易懂]完整的BSOD错误代码列表从STOP0x1到STOP0xC0000221一个死机(BSOD)的蓝屏,技术上称为一个STOP错误,若在Windows遭受了严重的错误,被迫“停”的问题。在任何Windows操作系统中都会出现BSOD错误,包括Windows10,Windows8,Windows7,WindowsVista,WindowsXP甚至Windows98/95。由于蓝屏错误让…

    2022年5月15日
    41
  • 反射型XSS漏洞

    反射型XSS漏洞实验项目反射型XSS实验综合性实验2020年10月22日一、实验综述1.实验目的及要求(1)什么是XSSXSS,全称跨站脚本,XSS是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。(2)XSS分成两类:一类是来自内部的,主要指的是利用程序自身的漏洞,构造跨站语句。另一类则是来自外部的***,主要指的自己构造XSS跨站漏洞网页或者寻找非目标机以外的有跨站漏洞的网页。如当我们要一个站点,我们自己构造一个有跨站漏洞的网页…

    2022年6月13日
    36
  • 如何用正确的姿势发微信群通知?「建议收藏」

    如何用正确的姿势发微信群通知?「建议收藏」人数众多的微信群里,你如何管理通知发放进度?想不想使用更高效的办法发通知?本文推荐给你一款小程序,帮助你轻松搞定微信群通知。(由于微信公众号外部链接的限制,文中的部分链接可能无法正确打开。如有需要,请点击文末的“阅读原文”按钮,访问可以正常显示外链的版本。)两难微信群被用来发通知,其实是工具使用场景错位。因为微信并不是高效办公的工具。否则腾讯也就不必开发企业微信,和

    2022年5月19日
    110

发表回复

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

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