HDU 4578 - Transformation - [加强版线段树]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578
There are n integers, a1, a2, …, an. The initial values of them are 0. There are four kinds of operations.
Operation 1: Add c to each number between ax and ay inclusive. In other words, do transformation ak<---ak+c, k = x,x+1,…,y.
Operation 2: Multiply c to each number between ax and ay inclusive. In other words, do transformation ak<---ak×c, k = x,x+1,…,y.
Operation 3: Change the numbers between ax and ay to c, inclusive. In other words, do transformation ak<---c, k = x,x+1,…,y.
Operation 4: Get the sum of p power among the numbers between ax and ay inclusive. In other words, get the result of axp+ax+1p+…+ay p.
Yuanfang has no idea of how to do it. So he wants to ask you to help him.
For each case, the first line contains two numbers n and m, meaning that there are n integers and m operations. 1 <= n, m <= 100,000.
Each the following m lines contains an operation. Operation 1 to 3 is in this format: "1 x y c" or "2 x y c" or "3 x y c". Operation 4 is in this format: "4 x y p". (1 <= x <= y <= n, 1 <= c <= 10,000, 1 <= p <= 3)
The input ends with 0 0.
题意:
给出一个序列,有下列操作:
- 对区间[x,y]全部加上c
- 对区间[x,y]全部乘上c
- 将区间[x,y]全部改成c
- 查询区间[x,y]的p次方和
题解:
加强版的线段树,需要三个lazy标记,一个add表示加法标记,一个mul表示乘法标记,一个alt表示修改标记,
同时由于p=1,2,3,所以可以有三个val值:sum1表示一次方和,sum2表示平方和,sum3表示立方和,
然后我们要确定三个标记的优先级:alt第一,mul第二,add第三,pushdown的时候要按照这样的顺序pushdown,
同时下压高优先级的标记,会影响到低优先级的标记,这个需要注意,
另外,在接收到父节点传过来的add标记时,更新自身时(update_add成员函数),要注意计算sum3,sum2,sum1的先后顺序,一定是sum3,sum2,sum1,
这三个sum计算的方法如下:
$\begin{array}{l} \left( {a + x} \right)^2 = a^2 + 2ax + x^2 \\ \left( {a_1 + x} \right)^2 + \left( {a_2 + x} \right)^2 + \cdots + \left( {a_n + x} \right)^2 = \left( {a_1 ^2 + \cdots + a_n ^2 } \right) + 2x\left( {a_1 + \cdots + a_n } \right) + nx^2 \\ \left( {a + x} \right)^3 = a^3 + 3a^2 x + 3ax^2 + x^3 \\ \left( {a_1 + x} \right)^3 + \left( {a_2 + x} \right)^3 + \cdots + \left( {a_n + x} \right)^3 = \left( {a_1 ^3 + \cdots + a_n ^3 } \right) + 3x\left( {a_1 ^2 + \cdots + a_n ^2 } \right) + 3x^2 \left( {a_1 + \cdots + a_n } \right) + nx^3 \\ \end{array}$
AC代码:
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const int maxn=+;
- const int MOD=;
- int n,m;
- /********************************* Segment Tree - st *********************************/
- struct Node
- {
- int l,r;
- int sum1,sum2,sum3;
- int add,mul,alt;
- void Update_Alt(int x)
- {
- x%=MOD;
- sum1 = (r-l+) * x % MOD;
- sum2 = (r-l+) * x % MOD * x % MOD;
- sum3 = (r-l+) * x % MOD * x % MOD * x % MOD;
- alt=x;
- add=;
- mul=;
- }
- void Update_Mul(int x)
- {
- x%=MOD;
- sum1 = sum1 % MOD * x % MOD;
- sum2 = sum2 % MOD * x % MOD * x % MOD;
- sum3 = sum3 % MOD * x % MOD * x % MOD * x % MOD;
- mul = mul % MOD * x % MOD;
- add = add % MOD * x % MOD;
- }
- void Update_Add(int x)
- {
- x%=MOD;
- sum3 = ( sum3%MOD + *x%MOD*sum2%MOD + *x%MOD*x%MOD*sum1%MOD + (r-l+)*x%MOD*x%MOD*x%MOD ) % MOD;
- sum2 = ( sum2%MOD + *x%MOD*sum1%MOD + (r-l+)%MOD*x%MOD*x%MOD ) % MOD;
- sum1 = ( sum1%MOD + (r-l+)%MOD*x%MOD ) % MOD;
- add=(add%MOD+x)%MOD;
- }
- }node[*maxn];
- void Pushdown(int root)
- {
- int ls=root*, rs=root*+;
- if(node[root].alt!=)
- {
- node[ls].Update_Alt(node[root].alt);
- node[rs].Update_Alt(node[root].alt);
- node[root].alt=;
- }
- if(node[root].mul!=)
- {
- node[ls].Update_Mul(node[root].mul);
- node[rs].Update_Mul(node[root].mul);
- node[root].mul=;
- }
- if(node[root].add!=)
- {
- node[ls].Update_Add(node[root].add);
- node[rs].Update_Add(node[root].add);
- node[root].add=;
- }
- }
- void Pushup(int root)
- {
- int ls=root*, rs=root*+;
- node[root].sum1=(node[ls].sum1+node[rs].sum1)%MOD;
- node[root].sum2=(node[ls].sum2+node[rs].sum2)%MOD;
- node[root].sum3=(node[ls].sum3+node[rs].sum3)%MOD;
- }
- void Build(int root,int l,int r) //对区间[l,r]建树
- {
- if(l>r) return;
- node[root].l=l; node[root].r=r;
- node[root].sum1=;
- node[root].sum2=;
- node[root].sum3=;
- node[root].alt=;
- node[root].add=;
- node[root].mul=;
- if(l<r)
- {
- int mid=l+(r-l)/;
- Build(root*,l,mid);
- Build(root*+,mid+,r);
- Pushup(root);
- }
- }
- void Alt(int root,int st,int ed,ll val) //区间[st,ed]全部改成val
- {
- if(st>node[root].r || ed<node[root].l) return;
- if(st<=node[root].l && node[root].r<=ed) node[root].Update_Alt(val);
- else
- {
- Pushdown(root);
- Alt(root*,st,ed,val);
- Alt(root*+,st,ed,val);
- Pushup(root);
- }
- }
- void Mul(int root,int st,int ed,ll val) //区间[st,ed]全部加上val
- {
- if(st>node[root].r || ed<node[root].l) return;
- if(st<=node[root].l && node[root].r<=ed) node[root].Update_Mul(val);
- else
- {
- Pushdown(root);
- Mul(root*,st,ed,val);
- Mul(root*+,st,ed,val);
- Pushup(root);
- }
- }
- void Add(int root,int st,int ed,ll val) //区间[st,ed]全部加上val
- {
- if(st>node[root].r || ed<node[root].l) return;
- if(st<=node[root].l && node[root].r<=ed) node[root].Update_Add(val);
- else
- {
- Pushdown(root);
- Add(root*,st,ed,val);
- Add(root*+,st,ed,val);
- Pushup(root);
- }
- }
- int Query(int root,int st,int ed,int p) //查询区间[st,ed]的p次方和
- {
- if(st>node[root].r || ed<node[root].l) return ;
- if(st<=node[root].l && node[root].r<=ed)
- {
- if(p==) return node[root].sum1;
- if(p==) return node[root].sum2;
- if(p==) return node[root].sum3;
- }
- else
- {
- Pushdown(root);
- int ls=Query(root*,st,ed,p)%MOD;
- int rs=Query(root*+,st,ed,p)%MOD;
- Pushup(root);
- return (ls+rs)%MOD;
- }
- }
- /********************************* Segment Tree - st *********************************/
- int main()
- {
- while(scanf("%d%d",&n,&m) && n*m!=)
- {
- Build(,,n);
- for(int i=;i<=m;i++)
- {
- int op; scanf("%d",&op);
- if(op==)
- {
- int x,y,k;
- scanf("%d%d%d",&x,&y,&k);
- Add(,x,y,k);
- }
- if(op==)
- {
- int x,y,k;
- scanf("%d%d%d",&x,&y,&k);
- Mul(,x,y,k);
- }
- if(op==)
- {
- int x,y,k;
- scanf("%d%d%d",&x,&y,&k);
- Alt(,x,y,k);
- }
- if(op==)
- {
- int l,r,p;
- scanf("%d%d%d",&l,&r,&p);
- printf("%d\n",Query(,l,r,p));
- }
- }
- }
- }
HDU 4578 - Transformation - [加强版线段树]的更多相关文章
- HDU 4578 Transformation (线段树)
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)T ...
- HDU 4578——Transformation——————【线段树区间操作、确定操作顺序】
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)T ...
- HDU - 4578 Transformation(线段树区间修改)
https://cn.vjudge.net/problem/HDU-4578 题意 4种操作,区间加,区间乘,区间变为一个数,求区间的和.平方和以及立方和. 分析 明显线段树,不过很麻烦..看kuan ...
- HDU 4578 Transformation (线段树区间多种更新)
http://acm.hdu.edu.cn/showproblem.php?pid=4578 题目大意:对于一个给定序列,序列内所有数的初始值为0,有4种操作.1:区间(x, y)内的所有数字全部加上 ...
- hdu 4578 Transformation(线段树)
线段树上的多操作... 题目大意: 树上 的初始值为0,然后有下列三种操作和求和. 1 x y c 在X-Y的之间全部加上C. 2 x y c 在X-Y的之间全部乘上C. 3 x y c ...
- Hdu 4578 Transformation (线段树 分类分析)
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)T ...
- hdu 5700区间交(线段树)
区间交 Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...
- Snacks HDU 5692 dfs序列+线段树
Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...
- HDU 4578 Transformation --线段树,好题
题意: 给一个序列,初始全为0,然后有4种操作: 1. 给区间[L,R]所有值+c 2.给区间[L,R]所有值乘c 3.设置区间[L,R]所有值为c 4.查询[L,R]的p次方和(1<=p< ...
随机推荐
- Simply Syntax(思维)
Simply Syntax Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5551 Accepted: 2481 Des ...
- C++实现按1的个数排序
题目内容:有一些0.1字符串,将其按1的个数的多少的顺序进行输出. 输入描述:本题只有一组测试数据.输入数据由若干数字组成,它是由若干个0和1组成的数字. 输出描述:对所有输入的数据,按1的个数进行生 ...
- Visual Studio 添加SVN插件
这两天为了开发一个移动混合式的框架,被迫去学习去使用VisualStudio,这玩意当年离开校园就再也没用过了,再次看到感觉还是很眼熟...,这篇文件就简单说明下VS下怎么安装SVN插件吧: 1 首先 ...
- js中对象的深度复制
// 对象的深度复制 cloneObj(oldObj) var cloneObj = function (obj) { var newObj = {}; if (obj instanceof Arra ...
- 第一个map reduce程序
完成了第一个mapReduce例子,记录一下. 实验环境: hadoop在三台ubuntu机器上部署 开发在window7上进行 hadoop版本2.2.0 下载了hadoop-eclipse-plu ...
- Splash scroll_position 属性
scroll_position属性用于控制页面上下或左右滚动,如下,表示控制页面向下滚动 400 像素值并返回结果图, function main(splash, args) assert(splas ...
- js数组sort方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- flask实现简单的接收json返回json的接口
结合http://docs.jinkan.org/docs/flask/quickstart.html#a-minimal-application这个flask文档实现 #!/usr/bin/pyth ...
- OAuth网络协议(转)
一.应用场景 为了理解OAuth的适用场合,让我举一个假设的例子. 有一个"云冲印"的网站,可以将用户储存在Google的照片,冲印出来.用户为了使用该服务,必须让"云冲 ...
- -webkit-transition -moz-transition transition
-webkit-transition -moz-transition transition 可以定义动画的变化时间曲线-webkit-transition-timing-function: ease ...