这个题让我重新学习了加 乘 在区间的操作

题解:http://blog.csdn.net/guognib/article/details/25324025?utm_source=tuicool&utm_medium=referral

代码:也是参考上面的写的

注:确实有优先级,加只影响自己,乘会影响加,重新设定值会清零所有的标记

所以向下传的时候,乘和加的操作都晚于最后一次设定值,然后乘的操作要先于加

所以要先传递set 然后是mul 然后是add

#include <stdio.h>
#include <string.h>
#include <string>
#include <math.h>
#include <stack>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=1e5+;
const int mod=;
int q[][N<<],setval[N<<],add[N<<],mul[N<<];
void pushup(int rt){
for(int i=;i<;++i)
q[i][rt]=(q[i][rt<<]+q[i][rt<<|])%mod;
}
void downset(int rt,int c,int len){
int a[];a[]=c;
for(int i=;i<=;++i)
a[i]=a[i-]*a[]%mod;
for(int i=;i<;++i)
q[i][rt]=a[i+]*len%mod;
setval[rt]=c;
add[rt]=;
mul[rt]=;
}
void downadd(int rt,int c,int len){
int a[];a[]=c;
for(int i=;i<=;++i)
a[i]=a[i-]*a[]%mod;
q[][rt]=q[][rt]+a[]*len%mod+*a[]%mod*q[][rt]%mod+*a[]%mod*q[][rt]%mod;
q[][rt]=q[][rt]+a[]*len%mod+*a[]%mod*q[][rt]%mod;
q[][rt]=q[][rt]+a[]*len%mod;
for(int i=;i<;++i)q[i][rt]%=mod;
add[rt]=(add[rt]+c)%mod;
}
void downmul(int rt,int c,int len){
int a[];a[]=c;
for(int i=;i<=;++i)
a[i]=a[i-]*a[]%mod;
for(int i=;i<;++i)
q[i][rt]=(q[i][rt]*a[i+])%mod;
mul[rt]=(mul[rt]*c)%mod;
add[rt]=(add[rt]*c)%mod;
}
void down(int rt,int l,int r){
int m=(l+r)>>;
if(setval[rt]!=-){
downset(rt<<,setval[rt],m-l+);
downset(rt<<|,setval[rt],r-m);
setval[rt]=-;
}
if(mul[rt]!=){
downmul(rt<<,mul[rt],m-l+);
downmul(rt<<|,mul[rt],r-m);
mul[rt]=;
}
if(add[rt]!=){
downadd(rt<<,add[rt],m-l+);
downadd(rt<<|,add[rt],r-m);
add[rt]=;
}
}
int op,c;
void modify(int rt,int l,int r,int x,int y){
if(x<=l&&r<=y){
if(op==)downadd(rt,c,r-l+);
else if(op==)downmul(rt,c,r-l+);
else downset(rt,c,r-l+);
return;
}
int m=(l+r)>>;
down(rt,l,r);
if(x<=m)modify(rt<<,l,m,x,y);
if(y>m)modify(rt<<|,m+,r,x,y);
pushup(rt);
}
int ask(int rt,int l,int r,int x,int y){
if(x<=l&&r<=y)return q[c-][rt];
int ans=,m=(l+r)>>;
down(rt,l,r);
if(x<=m)ans=(ans+ask(rt<<,l,m,x,y))%mod;
if(y>m)ans=(ans+ask(rt<<|,m+,r,x,y))%mod;
return ans;
}
int main(){
int n,m;
while(~scanf("%d%d",&n,&m)){
if(!n&&!m)break;
for(int i=;i<=*n;++i){
q[][i]=q[][i]=q[][i]=add[i]=;
mul[i]=;
setval[i]=-;
}
while(m--){
int x,y;
scanf("%d%d%d%d",&op,&x,&y,&c);
if(op<=)modify(,,n,x,y);
else printf("%d\n",ask(,,n,x,y));
}
}
return ;
}

HDU4578 Transformation 线段树的更多相关文章

  1. 30-Transformation(HDU4578)-区间线段树(复杂)

    http://acm.hdu.edu.cn/showproblem.php?pid=4578 Transformation Time Limit: 15000/8000 MS (Java/Others ...

  2. Transformation 线段树好题 好题 (独立写出来对线段树不容易)

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

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

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

  4. hdu 4578 Transformation 线段树

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

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

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

  6. HDU-4578 Transformation(线段树的多种区间操作)

    http://acm.hdu.edu.cn/showproblem.php?pid=4578 Time Limit: 15000/8000 MS (Java/Others)    Memory Lim ...

  7. 【HDU4578 Transformation】线段树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578 题意:有一个序列,有四种操作: 1:区间[l,r]内的数全部加c. 2:区间[l,r]内的数全部 ...

  8. HDU - 4578 Transformation(线段树区间修改)

    https://cn.vjudge.net/problem/HDU-4578 题意 4种操作,区间加,区间乘,区间变为一个数,求区间的和.平方和以及立方和. 分析 明显线段树,不过很麻烦..看kuan ...

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

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

随机推荐

  1. multimap和multiset 认知和使用

    之前只是在C++ Primer里面看过关联容器,可能因为没有实际用过,只是看看,所以导致用的时候并不熟悉: 在这之前,map和set的特性应该要了解,map是关联数组,也就是由键值对组成的,而set只 ...

  2. xcode 上 crash 调试的三种方法

    最近有新人问crash调试方法,简介记录如下: 模拟器调试 打开控制台查看输出日志 显示出错的行数 显示出错的函数iOS Crash跟踪 真机调试 首先修改真机调试的 bundle ID,使代码可以进 ...

  3. spring +hibernate 启动优化【转】

    最近在负责一个大项目,项目组成员包括项目经理大概10个人左右.项目技术用struts+spring+hibernate实现.项目的规模相对来说是比较大的,总共有10大模块,每个大模块又分为有十几个.甚 ...

  4. Extjs4.2——bbar的默认类型(xtype)

    bbar:在Panel经常使用的工具栏 如下面的示例——这将牵涉本文要追寻的问题:在下面的Panel中的bbar第一个组件明确指定的xtype:'button',第二个没有明确指出,那么它是何类型,为 ...

  5. eval()字符串转成对象

    var s = "{a:1,b:2}"; console.log(typeof s); s = eval("(" + s + ")"); c ...

  6. 在js中获取easyui datagrid的数据

    可以在页面对datagrid的数据直接进行修改,然后提交到数据库,但是要求在提交前获取datagrid的所有行的数据.API提供了getData方法,但是怎么用了,没说. 最后这样写才搞定 var a ...

  7. Kafka操作

    http://blog.csdn.net/xiao_jun_0820/article/details/46831203 http://blog.csdn.net/xcockroach/article/ ...

  8. POJ 1850 Code(组合数)

    http://poj.org/problem?id=1850 题意 :给定字符串,系统是用字符串组成的,字符串是按字典序排的.编码系统有三条规则,1这些的单词的长度是由小到大的,2相同长度的按字母在字 ...

  9. php构造函数construct用法注意事项

    <?php class A { //特别注意,这里的下划线为两个 function __construct() { echo "I am the constructor of A.&l ...

  10. BZOJ 3925 ZJOI2015 地震后的幻想乡

    假设我们用了边权前i小的边使得图连通,那么对答案的贡献为i/m+1 又因为期望的线性性质,我们只需要求用了i条边就可以了 不妨设g(S)(i)表示用了i条边使得点集S连通的概率 设f(S)(i)表示用 ...