线段树上的多操作。。。

题目大意:

树上 的初始值为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(线段树)的更多相关文章

  1. HDU 4578 Transformation --线段树,好题

    题意: 给一个序列,初始全为0,然后有4种操作: 1. 给区间[L,R]所有值+c 2.给区间[L,R]所有值乘c 3.设置区间[L,R]所有值为c 4.查询[L,R]的p次方和(1<=p< ...

  2. hdu 4578 Transformation 线段树

    没什么说的裸线段树,注意细节就好了!!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> ...

  3. hdu 4578 Transformation 线段树多种操作裸题

    自己写了一个带结构体的WA了7.8次 但是测了几组小数据都对..感觉问题应该出在模运算那里.写完这波题解去对拍一下. 以后线段树绝不写struct!一般的struct都带上l,r 但是一条线段的长度确 ...

  4. Transformation HDU - 4578(线段树——懒惰标记的妙用)

    Yuanfang is puzzled with the question below: There are n integers, a 1, a 2, …, a n. The initial val ...

  5. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  6. hdu 4288 离线线段树+间隔求和

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  7. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  8. HDU 4578 - Transformation - [加强版线段树]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578 Problem Description Yuanfang is puzzled with the ...

  9. HDU 4578 Transformation (线段树)

    Transformation Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)T ...

  10. HDU 4578——Transformation——————【线段树区间操作、确定操作顺序】

    Transformation Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)T ...

随机推荐

  1. 苹果官方 Crash文件分析方法 (iOS系统Crash文件分析方法)

    对于提交的苹果官方的app,在审核的时候会给我们一些crash文件,对于这些有用的文件,里面是关于我们的bug的一些信息,那么该如何去调试呢 第一步:在任意目录创建一个目录,用来调试crash,我这里 ...

  2. iOS 静态类库项目的建立与使用

    iOS 静态类库项目的建立与使用   新建 Xcode workspace 打开 Xcode , 选择 File -> New -> Workspace , 将 Workspace 命名为 ...

  3. 物联网操作系统HelloX开发者入门指南

    HelloX开发者入门指南 HelloX是聚焦于物联网领域的操作系统开发项目,可以通过百度搜索"HelloX",获取详细信息.当前开发团队正在进一步招募中,欢迎您的了解和加入.如果 ...

  4. 批量添加-fno-objc-arc

    http://syxiaqj.github.io/2014/02/28/bee-learning-1/ 4.批量添加-fno-objc-arc 因为BeeFramework是一个非RAC的框架,现在X ...

  5. Delphi 自带的那个 Hand 光标很难看?没关系,一行代码解决问题:

    Delphi 自带的那个 Hand 光标很难看?没关系,一行代码解决问题: Screen.Cursors[crHandPoint] := LoadCursor(0, IDC_HAND);放在主窗体 O ...

  6. HDU 5387 Clock

    题意:给一个时间,求三个时针之间的夹角,分数表示. 解法:算算算.统一了一下分母. 代码: #include<stdio.h> #include<iostream> #incl ...

  7. 大数据性能调优之HBase的RowKey设计

    1 概述 HBase是一个分布式的.面向列的数据库,它和一般关系型数据库的最大区别是:HBase很适合于存储非结构化的数据,还有就是它基于列的而不是基于行的模式. 既然HBase是采用KeyValue ...

  8. String.valueOf()

    1. 由 基本数据型态转换成 String String 类别中已经提供了将基本数据型态转换成 String 的 static 方法 也就是 String.valueOf() 这个参数多载的方法 有下 ...

  9. codeforces 681D Gifts by the List dfs+构造

    题意:给你一个森林,表示其祖先关系(自己也是自己的祖先),每个人有一个礼物(要送给这个人的固定的一个祖先) 让你构造一个序列,使得的对于每个人,这个序列中第一个出现的他的祖先,是他要送礼物的的那个祖先 ...

  10. [python]倒计时实现

    for num in range(5,0,-1):     time.sleep(1)     sys.stdout.flush()     sys.stdout.write('\rPlease Wa ...