HDU4578 Transformation 线段树
这个题让我重新学习了加 乘 在区间的操作
题解: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 线段树的更多相关文章
- 30-Transformation(HDU4578)-区间线段树(复杂)
http://acm.hdu.edu.cn/showproblem.php?pid=4578 Transformation Time Limit: 15000/8000 MS (Java/Others ...
- Transformation 线段树好题 好题 (独立写出来对线段树不容易)
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)T ...
- 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 但是一条线段的长度确 ...
- HDU-4578 Transformation(线段树的多种区间操作)
http://acm.hdu.edu.cn/showproblem.php?pid=4578 Time Limit: 15000/8000 MS (Java/Others) Memory Lim ...
- 【HDU4578 Transformation】线段树
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578 题意:有一个序列,有四种操作: 1:区间[l,r]内的数全部加c. 2:区间[l,r]内的数全部 ...
- HDU - 4578 Transformation(线段树区间修改)
https://cn.vjudge.net/problem/HDU-4578 题意 4种操作,区间加,区间乘,区间变为一个数,求区间的和.平方和以及立方和. 分析 明显线段树,不过很麻烦..看kuan ...
- HDU 4578 - Transformation - [加强版线段树]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578 Problem Description Yuanfang is puzzled with the ...
随机推荐
- To change the sharepoint CA port
Set-SPCentralAdministration -Port <port number> to fix the error: Got this error: Failed to re ...
- linux内核分析之内存管理
1.struct page /* Each physical page in the system has a struct page associated with * it to keep tra ...
- 3.4 spring- lookup-method 子元素的使用与解析
1. lookup-method的应用: 1.1 子元素lookup-method 似乎不是很常用,但是在某些时候他的确是非常有用的属性,通常我们称它为 "获取器注入" . 引用 ...
- [转载]用.NET开发的磁力搜索引擎——Btbook.net
去年10月份开始研究相关的协议与资料,中途乱七八糟的事情差点没坚持下来,寒假里修修补补上礼拜把Btbook发布了,经过社交网络的推广之后,上线第三天UV就达到了两万多,也算是对这几个月工作的一点肯定吧 ...
- spoj 390
简单题 记得uva上有个一样的 画个图就好了 #include <cstdio> #include <cmath> const double pi = acos(-1); ...
- js 计时器
<html><head><script type="text/javascript">var count=0;var t ;function t ...
- hdu 4675 GCD of Sequence
数学题! 从M到1计算,在计算i的时候,算出原序列是i的倍数的个数cnt: 也就是将cnt个数中的cnt-(n-k)个数变掉,n-cnt个数变为i的倍数. 且i的倍数为t=m/i; 则符合的数为:c[ ...
- poj 1095 Trees Made to Order 卡特兰数
这题用到了卡特兰数,详情见:http://www.cnblogs.com/jackge/archive/2013/05/19/3086519.html 解体思路详见:http://blog.csdn. ...
- swift苹果的下一代语言
http://numbbbbb.github.io/the-swift-programming-language-in-chinese/chapter1/01_swift.html 有时间再看,bas ...
- redis info命令结果释疑
redis的性能数据这块用 info 命令就可以获取的比较全面了,下面是对info信息返回值的解释: # 参考:http://redis.io/commands/info # # # Server r ...