线段树上的多操作。。。

题目大意:

树上 的初始值为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;
}

转载于:https://www.cnblogs.com/pangblog/p/3367770.html

hdu 4578 Transformation(线段树)相关推荐

  1. HDU 2795 Billboard (线段树+贪心)

    HDU 2795 Billboard (线段树+贪心) 手动博客搬家:本文发表于20170822 21:30:17, 原地址https://blog.csdn.net/suncongbo/articl ...

  2. HDU 5861 Road 线段树区间更新单点查询

    题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5861 Road Time Limit: 12000/6000 MS (Java/Othe ...

  3. hdu 3308 LCIS 线段树 + 区间合并

    传送门 文章目录 题意: 思路: 题意: 思路: 日常水一篇题解. 带修改的求区间连续的递增序列,我们考虑用线段树维护. 直接维护mlenmlenmlen是区间最长的递增序列,lslsls是从左端点开 ...

  4. hdu 4747 mex 线段树+思维

    http://acm.hdu.edu.cn/showproblem.php?pid=4747 题意: 我们定义mex(l,r)表示一个序列a[l]....a[r]中没有出现过得最小的非负整数, 然后我 ...

  5. hdu 1542 Atlantis (线段树+扫描线)

    http://acm.hdu.edu.cn/showproblem.php?pid=1542 单纯的线段树+扫描线求面积并,需要离散化. code: #include <cstdlib> ...

  6. YJJ's Salesman HDU - 6447(线段树 单点更新+DP思想)

    YJJ's Salesman 题目链接:HDU - 6447 题意:一个1e9*1e9的地图,要求由(0, 0) -> (1e9, 1e9):只能向下,向右, 向右下移动:地图中有n个点,有宝藏 ...

  7. HDU 4288 Coder [线段树]

    维护一个可以插入删除的有序序列,每次询问序列中位置mod5=3的数的和. CodeForces原题,因为时限给的太宽,数据太水,STL可以暴力过. 用线段树和平衡树都可以做这题,线段树需要先离散化,然 ...

  8. hdu 1540(线段树单点更新 区间合并)

    解题思路:这一题要求的是连续区间,所以可以把它的子区间合并,这里运用线段树,但是在保存节点信息的方面要做一点修改 lsum:从这个区间的左端点往右能够找到的最大连续区间: rsum:从这个区间的右端点 ...

  9. hdu 1255(线段树求重叠面积)

    扫描线求矩形重叠面积:http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html http://www.tuicool.co ...

  10. hdu 3577(线段树区间更新)

     题意:输入一个t,表示有t组测试数据: 接下来一行,输入两个数,k,m,其中k表示这个辆车最多可以坐这么多人,m表示有m次询问能否上车: 每一次询问,输入两个数a,b,表示该乘客能否在a站台上车 ...

最新文章

  1. 695.岛屿的最大面积
  2. 【翻译】What is State Machine Diagram(什么是状态机图)?
  3. javase基础复习攻略《七》
  4. php 数据接口,初识 php 接口
  5. 职业年金退休能拿多少?怎么算的?
  6. 那些高曝光的Annotation(@ComponentScan、@PropertySource与@PropertySources、@Import与ImportResource)
  7. 长尾问题 数据不平衡 学习笔记
  8. 傅里叶变换的相关实验——matlab实现
  9. matlab lte rsrp,为什么选择 FieldFox 手持式分析仪?- 更宽带宽,更高精度
  10. leetcode845. 数组中的最长山脉
  11. 迪文屏学习系列之数据录入
  12. 传感器发展历史,你知道吗?(图文并茂)
  13. OSChina 周六乱弹 —— 周末万岁!
  14. C语言每日一练——第35天:打印菱形
  15. 魔兽3的地图脚本文件简单分析图
  16. vue中activated和deactivated是什么
  17. 李开复:创业开始别想太高 年轻人多看国外网站
  18. 不属于ipo模型的 python_以下不属于IPO模型的是:
  19. android 九宫格图案解锁
  20. 实战PyQt5: 050-选项卡控件QTabWidget

热门文章

  1. python编程高手之路——函数调用
  2. 循环序列模型 —— 1.9 GRU单元(门控循环单元)
  3. TensorFlow第八步 Nesterov's accelerated gradient descent+L2 regularization
  4. H264中DCT变换,量化,反量化,反DCT变换
  5. 方法重载与重写,返回类型
  6. Linux常用命令—权限管理命令—其他权限管理命令
  7. A. Gamer Hemose
  8. 【深度3】相机选择-精度和曝光需求计算 - 输入:1 被测试物体的最小体积 2 被测物体的移动相对速度
  9. [gstreamer] [002] porting from 0.10 to 1.0 knew how
  10. 匹配指定内容的div_HTML背景色教程–如何更改Div背景色,并通过代码示例进行了说明...