HDU ACM 4578 Transformation->段树-间隔的变化
分析:复杂的经营分部树。
只有一个查询操作,这是要求[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;
}
版权声明:本文博主原创文章。博客,未经同意不得转载。
HDU ACM 4578 Transformation->段树-间隔的变化的更多相关文章
- HDU 6356.Glad You Came-线段树(区间更新+剪枝) (2018 Multi-University Training Contest 5 1007)
6356.Glad You Came 题意就是给你一个随机生成函数,然后从随机函数里确定查询的左右区间以及要更新的val值.然后最后求一下异或和就可以了. 线段树,区间最大值和最小值维护一下,因为数据 ...
- HDU 5649.DZY Loves Sorting-线段树+二分-当前第k个位置的数
DZY Loves Sorting Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Oth ...
- HDU 4578 - Transformation - [加强版线段树]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578 Problem Description Yuanfang is puzzled with the ...
- HDU 4578 Transformation (线段树区间多种更新)
http://acm.hdu.edu.cn/showproblem.php?pid=4578 题目大意:对于一个给定序列,序列内所有数的初始值为0,有4种操作.1:区间(x, y)内的所有数字全部加上 ...
- HDU 4578——Transformation——————【线段树区间操作、确定操作顺序】
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)T ...
- HDU 4578 Transformation (线段树)
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)T ...
- HDU 1698 Just a Hook (段树更新间隔)
Problem Description In the game of DotA, Pudge's meat hook is actually the most horrible thing for m ...
- HDU - 4578 Transformation(线段树区间修改)
https://cn.vjudge.net/problem/HDU-4578 题意 4种操作,区间加,区间乘,区间变为一个数,求区间的和.平方和以及立方和. 分析 明显线段树,不过很麻烦..看kuan ...
- Hdu 4578 Transformation (线段树 分类分析)
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)T ...
随机推荐
- Hadoop之MapReduce程序应用三
摘要:MapReduce程序进行数据去重. 关键词:MapReduce 数据去重 数据源:人工构造日志数据集log-file1.txt和log-file2.txt. log-file1.txt内容 ...
- About VirtualBoxImages.com
About VirtualBoxImages.com | VirtualBoxImages.com About VirtualBoxImages.com About: VirtualBoxImages ...
- Python性能分析指南 - 技术翻译 - 开源中国社区
http://www.oschina.net/translate/python-performance-analysis
- 微信 SDK 不能 分享
说多了都是泪水,真的. 前段时间,做好了微信的分享功能,测试通过的,最近我又跑了一遍用例,发现不能启动微信客户端了,怎么都启动不了,日志如下:ignore wechat app signature v ...
- SESC中的热量模拟器
SESC安装见前文 配置sesc支持热量模拟 ../sesc/configure --enable-power --enable-therm make 遇到问题: 1 找不到 liblevmar.a ...
- [Leetcode]-ReverseLinkedList
题目:单链表取反 #include <stdlib.h> #include <stdio.h> typedef struct node *list; typedef struc ...
- adt-bundle更新eclipse,以及搭建android环境
曾经开发一直去android官网下载adt-bundle的.里面已经包括了eclipse和android SDK,搭建android环境特别方便,仅仅须要3步:1.下载并安装jdk(也就是jar se ...
- SVN冲突解决详解
在: http://blog.csdn.net/windone0109/article/details/4857044
- NVL NVL2 NVLIF
========Oracle=======NVL (expr1, expr2)->expr1为NULL,返回expr2:不为NULL,返回expr1.注意两者的类型要一致
- 用XAML做网页!!—终结篇
原文:用XAML做网页!!-终结篇 迄今为止的设计都很顺利,但这次就不得不接触我前面所说的非常糟糕的流文档了,但在此之前先来把标题弄好: <Border BorderBrush="#6 ...