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 ...
随机推荐
- Java注解处理器(转)
Java中的注解(Annotation)是一个很神奇的东西,特别现在有很多Android库都是使用注解的方式来实现的.一直想详细了解一下其中的原理.很有幸阅读到一篇详细解释编写注解处理器的文章.本文的 ...
- git初探
1 Linux下Git和GitHub环境的搭建 第一步: 安装Git,使用命令 "sudo apt-get install git" 第二步: 到GitHub上创建GitHub帐号 ...
- MySQL的基本命令
MySQL的基本命令 启动:net start mySql; 进入:mysql -u root -p/mysql -h localhost -u root -p databaseName; 列出数据库 ...
- 如何循环遍历document.querySelectorAll()方法返回的结果
使用JavaScript的forEach方法,我们可以轻松的循环一个数组,但如果你认为document.querySelectorAll()方法返回的应该是个数组,而使用forEach循环它: /* ...
- spoj 297
就是对距离进行二分找最大值 .... #include <cstring> #include <cstdio> #include <algorithm> #incl ...
- 关于Spark中RDD的设计的一些分析
RDD, Resilient Distributed Dataset,弹性分布式数据集, 是Spark的核心概念. 对于RDD的原理性的知识,可以参阅Resilient Distributed Dat ...
- openssl安装问题导致nginx添加ssl模块失败
问题:./nginx: undefined symbol: EVP_rc4_hmac_md5 sudo vi /etc/ld.so.conf #把openssl安装路径加入sudo ldconfig ...
- CF 369 B. Valera and Contest
http://codeforces.com/contest/369/problem/B 题意 :n, k, l, r, sall, sk,n代表的是n个人,这n个人的总分是sall,每个人的得分大于 ...
- linux 文件比对总结
1. 过滤a.log的重复数据 #统计 cat datatest.log|sort|uniq -d |wc -l #放入b.log cat datatest.log|sort|uniq -d > ...
- iOS开发--TableView详细解释
-.建立 UITableView DataTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 420)]; [Data ...