HDU 4578 Transformation (线段树区间多种更新)
http://acm.hdu.edu.cn/showproblem.php?pid=4578
题目大意:对于一个给定序列,序列内所有数的初始值为0,有4种操作。1:区间(x, y)内的所有数字全部加上C;2:区间(x, y)内所有数字全部乘C; 3:区间(x, y)内的所有数字全部重置为C;
4:输出区间(x, y)内所有数字的P次方的和。由于题目为多实例(至少10组样例),故很耿直的更新到叶子节点明显会TLE;因此需优化。可发现题目所有操作都是对区间进行,因此只需要更新
到区间内数字相同即可。再者注意可进行状态压缩,不需要的累加和累乘只标记即可,需要此部分时再往下更新;更新时先更新3,因为3会覆盖掉1和2;之后再进行累乘,因为累乘影响累加,累
加不影响累乘。注意细节即可。
- ///至少10组样例,则八秒实际上不多,需优化。
- ///由于所有操作都是对区间进行,故数字保存情况为
- ///分区间相同,因此只需要操作到区间数字相同时即可,不必处理到最下面的叶子节点
- #include <stdio.h>
- #include <algorithm>
- using namespace std;
- #define N 110000
- #define mod 10007
- #define lson rt<<1
- #define rson rt<<1|1
- struct tree
- {
- int l, r, add, mul, op, num;
- ///add记录累加的数,mul记录累乘的数,op记录操作的状态
- ///op为1表示区间内数字相同,op为0表示区间内数字不同,需向下
- ///继续进行操作,op为2表示区间被重新赋值,需向下更新(操作3)。
- int len()
- {
- return r-l+1;
- }
- }a[N<<2];
- void build(int l, int r, int rt)///初始化
- {
- a[rt].l = l;
- a[rt].r = r;
- a[rt].mul = a[rt].op = 1;
- a[rt].add = a[rt].num = 0;
- if(l==r)return ;
- int mid = (l+r)/2;
- build(l, mid, lson);
- build(mid+1, r, rson);
- }
- void Change(int rt, int op, int k)
- {
- if(op==3)///重新赋值,即再次初始化
- {
- a[rt].num = k%mod;
- a[rt].mul = 1;
- a[rt].add = 0;
- a[rt].op = 2;///重新赋值后子区间所有都重新覆盖
- }
- else if(op==2)
- {
- (a[rt].add *= k) %= mod;
- (a[rt].mul *= k) %= mod;
- (a[rt].num *= k) %= mod;
- }
- else
- {
- (a[rt].add += k) %= mod;
- (a[rt].num += k) %= mod;
- }
- }
- void Up(int rt)
- {
- if(a[lson].op && a[rson].op)///若子区间为同数字区间且两子区间数字相同,
- if(a[lson].num == a[rson].num)///则可向上合并给父区间
- {
- a[rt].num = a[lson].num;
- a[rt].op = 1;
- }
- }
- void Down(int rt)///向下的状态压缩,若不需此区间作答此区间暂时储存;
- { ///若需此区间作答则向下更新一层直到叶子节点
- if(a[rt].l != a[rt].r)
- {
- if(a[rt].op==2)
- {
- a[lson].num = a[rson].num = a[rt].num;
- a[lson].op = a[rson].op = 2;
- a[lson].add = a[rson].add = 0;
- a[lson].mul = a[rson].mul = 1;
- a[rt].add = 0;
- a[rt].mul = 1;
- a[rt].op = 1;
- }
- if(a[rt].mul>1)///注意此处,先更新乘法,因为累乘会影响累加的状态
- {
- (a[lson].num *= a[rt].mul) %= mod;
- (a[lson].add *= a[rt].mul) %= mod;
- (a[lson].mul *= a[rt].mul) %= mod;
- (a[rson].num *= a[rt].mul) %= mod;
- (a[rson].add *= a[rt].mul) %= mod;
- (a[rson].mul *= a[rt].mul) %= mod;
- a[rt].mul = 1;
- }
- if(a[rt].add)
- {
- (a[lson].num += a[rt].add) %= mod;
- (a[lson].add += a[rt].add) %= mod;
- (a[rson].num += a[rt].add) %= mod;
- (a[rson].add += a[rt].add) %= mod;
- a[rt].add = 0;
- }
- }
- }
- void Update(int rt, int op, int l, int r, int k)
- {
- if(a[rt].l==l && a[rt].r==r && a[rt].op)///找到数字相同区间
- {
- Change(rt, op, k);///执行操作
- return ;
- }
- Down(rt);
- a[rt].op = 0;///假设默认区间数字已改变,标记为不同。
- int mid = (a[rt].l + a[rt].r)/2;
- if(mid>=r)Update(lson, op, l, r, k);
- else if(mid<l)Update(rson, op, l, r, k);
- else
- {
- Update(lson, op, l, mid, k);
- Update(rson, op, mid+1, r, k);
- }
- Up(rt);///执行操作后向上回溯,用已得到的子区间反馈负区间的状态
- }
- int Query(int rt, int l, int r, int p)
- {
- if(a[rt].l==l && a[rt].r==r && a[rt].op)///找到同数字区间即可计算
- {
- int ans = 1;
- for(int i=1; i<=p; i++)///一个p次方
- (ans *= a[rt].num) %= mod;
- ans = (ans * a[rt].len())%mod; ///区间内所有p次方
- return ans;
- }
- Down(rt);
- int mid = (a[rt].l + a[rt].r)/2;
- if(mid>=r)return Query(lson, l, r, p);
- else if(mid<l)return Query(rson, l, r, p);
- else
- {
- int lans = Query(lson, l, mid, p);
- int rans = Query(rson, mid+1, r, p);
- return (lans+rans)%mod;
- }
- }
- int main()
- {
- int n, m;
- while(scanf("%d %d", &n, &m), m+n)
- {
- build(1, n, 1);
- int op, l, r, k;
- while(m--)
- {
- scanf("%d %d %d %d", &op, &l, &r, &k);
- if(op!=4)Update(1, op, l, r, k);///只要不为4都是更新操作
- else printf("%d\n", Query(1, l, r, k));
- }
- }
- return 0;
- }
HDU 4578 Transformation (线段树区间多种更新)的更多相关文章
- hdu 4578 Transformation 线段树多种操作裸题
自己写了一个带结构体的WA了7.8次 但是测了几组小数据都对..感觉问题应该出在模运算那里.写完这波题解去对拍一下. 以后线段树绝不写struct!一般的struct都带上l,r 但是一条线段的长度确 ...
- 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 4031 attack 线段树区间更新
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Subm ...
- hdu 5475 An easy problem(暴力 || 线段树区间单点更新)
http://acm.hdu.edu.cn/showproblem.php?pid=5475 An easy problem Time Limit: 8000/5000 MS (Java/Others ...
- HDU 3308 LCIS (线段树·单点更新·区间合并)
题意 给你一个数组 有更新值和查询两种操作 对于每次查询 输出相应区间的最长连续递增子序列的长度 基础的线段树区间合并 线段树维护三个值 相应区间的LCIS长度(lcis) 相应区间以左 ...
- HDU 3308 LCIS (线段树区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...
- hdu 4747【线段树-成段更新】.cpp
题意: 给出一个有n个数的数列,并定义mex(l, r)表示数列中第l个元素到第r个元素中第一个没有出现的最小非负整数. 求出这个数列中所有mex的值. 思路: 可以看出对于一个数列,mex(r, r ...
- hdu 5023(线段树区间染色,统计区间内颜色个数)
题目描述:区间染色问题,统计给定区间内有多少种颜色? 线段树模板的核心是对标记的处理 可以记下沿途经过的标记,到达目的节点之后一块算,也可以更新的时候直接更新到每一个节点 Lazy操作减少修改的次数( ...
随机推荐
- Unity Shader——Writing Surface Shaders(2)——Custom Lighting models in Surface Shaders
Surface Shader中的自定义光照模型 当你在编写 Surface Shaders 时,是在描述一个表面的属性(反射颜色.法线……),而且光的交互过程是由一个光照模型来计算的.内建的光照模型有 ...
- java mvc web 项目web.xml头改错了,死活加载不上springMvc的jar
Description Resource Path Location TypeOne or more constraints have not been satisfied. ...
- 解决php的“It is not safe to rely on the system’s timezone settings”问题
PHP调试的时候出现了警告: It is not safe to rely on the system解决方法,其实就是时区设置不正确造成的,本文提供了3种方法来解决这个问题. 实 际上,从PHP 5 ...
- [家里蹲大学数学杂志]第432期Hardy type inequalities
If $p>1$, $f\geq 0$, and $$\bex F(x)=\int_0^x f(t)\rd t, \eex$$ then $$\bee\label{Hardy:0 to x} \ ...
- Angular(2)
1.自定义指令,直接栗子: note:定义指定是驼峰,2部分 前缀+作用,but 调用 改驼峰首字母大写处为 (-首字母小写) <!DOCTYPE html><html lang= ...
- boost::asio::socket tcp 连接 在程序结束时崩溃。
刚开始的时候一直不知道怎么回事,不过幸好我有在每个class 的析构时都打印一条信息. 这个时候发现我的一个tcp_connection (就是自定义的一个连接类) 在最后才被析构. 所以感觉这里可能 ...
- ThinkPHP 3.2.3集成uploadify上传控件
uploadify控件有一个坑爹的问题,就是文件上传时会session丢失,官方解释http://www.uploadify.com/documentation/uploadify/using-ses ...
- Navicat链接Oracle提示ORA-12737
ORA-12737: Instant Client Light: unsupported server character set string Cause: The character set sp ...
- ios delegate你必须知道的事情
在我们的class中设计delegate的时候,我们通常会有几个注意事项. 假设我的class叫做MyClass,那我们可能会有定义一个MyClassDelegate这个protocol当作我的del ...
- 1,SFDC 管理员篇 - 基本设置
1, 公司配置 Setup | Administrator| Company Profile *Company Inforamtion:公司基础信息,License信息,重要的设置包括本地时间,币种, ...