hdu 4578 Transformation(线段树)
线段树上的多操作。。。
题目大意:
树上 的初始值为0,然后有下列三种操作和求和。
1 x y c 在X-Y的之间全部加上C。
2 x y c 在X-Y的之间全部乘上C。
3 x y c 在X-Y之间的全部变成C。
4 x y c 输出在X-Y之间的所有数的C方的和。。。
思路:
因为存在两种不兼容的操作(如果直接放一起的话会出现顺序不同的影响,(3+2)*4 和 3*4+2 显然是不一样的)
所以每次合并操作的时候 就要把子树的操作推下去清除掉。
当然 如果这个区间的所有值都是一样的话。那么可以直接进行操作。
然后就是Query了。
因为要求出很多的平方 或者 立方和。
那么我们就去找所有区间的值是一样的区间。拿出来现乘方 再算有多少个。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
#define maxn 100005
const int mod = 10007;
using namespace std; int add[maxn<<2];
int mul[maxn<<2];
int cov[maxn<<2];
int tre[maxn<<2];
int n,m; void pushdown(int num)
{
if(cov[num])//如果这个区间是值一样的
{
tre[num<<1]=tre[num<<1|1]=tre[num];
cov[num<<1]=cov[num<<1|1]=1;
add[num<<1]=add[num<<1|1]=0;
mul[num<<1]=mul[num<<1|1]=1;
cov[num]=0;
return;
}
if(add[num]!=0)//不一样的话 要把ADD推下去
{
if(cov[num<<1])
{
tre[num<<1]+=add[num];
tre[num<<1]%=mod;
}
else
{
pushdown(num<<1);
add[num<<1]+=add[num];
add[num<<1]%=mod;
} if(cov[num<<1|1])
{
tre[num<<1|1]+=add[num];
tre[num<<1|1]%=mod;
}
else
{
pushdown(num<<1|1);
add[num<<1|1]+=add[num];
add[num<<1|1]%=mod;
} add[num]=0;
}
if(mul[num]!=1)
{
if(cov[num<<1])
{
tre[num<<1]*=mul[num];
tre[num<<1]%=mod;
}
else
{
mul[num<<1]*=mul[num];
mul[num<<1]%=mod;
} if(cov[num<<1|1])
{
tre[num<<1|1]*=mul[num];
tre[num<<1|1]%=mod;
}
else
{
mul[num<<1|1]*=mul[num];
mul[num<<1|1]%=mod;
}
mul[num]=1;
}
} void build(int num,int s,int e)
{
add[num]=0;
mul[num]=1;
cov[num]=0;
tre[num]=0;
if(s==e)
{
cov[num]=1;
return;
}
int mid=(s+e)>>1;
build(lson);
build(rson);
} void update(int num,int s,int e,int l,int r,int val,int op)
{
if(l<=s && r>=e)
{
if(op==3)
{
add[num]=0;
mul[num]=1;
cov[num]=1;
tre[num]=val;
}
else
{
if(cov[num])
{
if(op==1)
{
tre[num]+=val;
tre[num]%=mod;
}
else
{
tre[num]*=val;
tre[num]%=mod;
}
}
else
{
pushdown(num); if(op==1)
{
add[num]+=val;
add[num]%=mod;
}
else
{
mul[num]*=val;
mul[num]%=mod;
}
}
}
return;
} pushdown(num); int mid=(s+e)>>1; if(l<=mid)update(lson,l,r,val,op);
if(r>mid)update(rson,l,r,val,op);
} int Q_Q(int num,int s,int e,int c)
{
printf("```%d\n",num);
int mid=(s+e)>>1;
if(cov[num]==1)
{
int tmp=1;
for(int aa=0;aa<c;aa++)
{
tmp*=tre[num];
tmp%=mod;
}
tmp*=(e-s+1);
tmp%=mod;
return tmp;
}
pushdown(num);
Q_Q(lson,c);
Q_Q(rson,c);
}
int query(int num,int s,int e,int l,int r,int c)
{
int mid=(s+e)>>1;
if(l==s && r==e)
{
if(cov[num])
{
int tmp=1;
while(c--)
{
tmp*=tre[num];
tmp%=mod;
}
tmp*=(e-s+1);
tmp%=mod;
return tmp;
}
}
pushdown(num); if(r<=mid)return query(lson,l,r,c);
else if(l>mid)return query(rson,l,r,c);
else return (query(lson,l,mid,c) + query(rson,mid+1,r,c))%mod;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0 && m==0)break;
int op,lef,rig,c;
build(1,1,n);
while(m--)
{
scanf("%d%d%d%d",&op,&lef,&rig,&c); if(op!=4)update(1,1,n,lef,rig,c,op);
else printf("%d\n",query(1,1,n,lef,rig,c)%mod);
}
}
return 0;
}
hdu 4578 Transformation(线段树)的更多相关文章
- HDU 4578 Transformation --线段树,好题
题意: 给一个序列,初始全为0,然后有4种操作: 1. 给区间[L,R]所有值+c 2.给区间[L,R]所有值乘c 3.设置区间[L,R]所有值为c 4.查询[L,R]的p次方和(1<=p< ...
- hdu 4578 Transformation 线段树
没什么说的裸线段树,注意细节就好了!!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> ...
- hdu 4578 Transformation 线段树多种操作裸题
自己写了一个带结构体的WA了7.8次 但是测了几组小数据都对..感觉问题应该出在模运算那里.写完这波题解去对拍一下. 以后线段树绝不写struct!一般的struct都带上l,r 但是一条线段的长度确 ...
- Transformation HDU - 4578(线段树——懒惰标记的妙用)
Yuanfang is puzzled with the question below: There are n integers, a 1, a 2, …, a n. The initial val ...
- hdu 4031 attack 线段树区间更新
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Subm ...
- hdu 4288 离线线段树+间隔求和
Coder Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- hdu 3016 dp+线段树
Man Down Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- HDU 4578 - Transformation - [加强版线段树]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578 Problem Description Yuanfang is puzzled with the ...
- 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 ...
随机推荐
- LA 4127 - The Sky is the Limit (离散化 扫描线 几何模板)
题目链接 非原创 原创地址:http://blog.csdn.net/jingqi814/article/details/26117241 题意:输入n座山的信息(山的横坐标,高度,山底宽度),计算他 ...
- JAVA中获取工程路径的方法
在jsp和class文件中调用的相对路径不同.在jsp里,根目录是WebRoot 在class文件中,根目录是WebRoot/WEB-INF/classes 当然你也可以用System.getProp ...
- BestCoder Round #35
A 题意:给出n个黑球,m个白球,每次取1个球,取了n+m次以后,会生成一个随机的01串S, 如果第i次取出的是黑球,则s[i]=1,如果是白色的,那么s[i]=0, 问01串在S中出现的期望次数 大 ...
- [反汇编练习] 160个CrackMe之010
[反汇编练习] 160个CrackMe之010. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...
- 【iOS-Cocos2d游戏开发之四】独自收集Cocos2d提供的字体!共57种(有对照的字体图)
本站文章均为李华明Himi原创,转载务必在明显处注明:(作者新浪微博:@李华明Himi) 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/iphone-c ...
- OOP——UML六种关系
UML定义的关系主要有:泛化.实现.依赖.关联.聚合.组合,这六种关系紧密程度依次加强,分别看一下 泛化 概念:泛化是一种一般与特殊.一般与具体之间关系的描述,具体描述建立在一般描述的基础之上,并对其 ...
- shell 中grep命令详解
用‘grep’搜索文本文件如果您要在几个文本文件中查找一字符串,可以使用‘grep’命令.‘grep’在文本中搜索指定的字符串.举个例子:假设您正在‘/usr/src/linux/Documentat ...
- DirectX截图黑屏的解决办法
好久没有更新博客了,今天开始继续耕耘. 生活要继续 工作要继续 梦想也一定要继续! 之前写过一篇关于DirectX截屏的文章,其中有网友留言提到了截图黑屏的问题,于是这些日子研究了一下,与大家一同分享 ...
- 在linux的shell里访问一个URL
在linux上访问一个网址有四种方法 1.elinks,用法举例: [weishusheng@centOS6 ~]$ elinks -dump http://www.baidu.com 2. wget ...
- 【转】STL空间配置器
STL空间配置器(allocator)在所有容器内部默默工作,负责空间的配置和回收.STL标准为空间配置器定义了标准接口(可见<STL源码剖析>P43).而具体实现细节则由各编译器实现版本 ...