题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578

四种操作:查询、加法、乘法、改数。应该是需要维护三个lazy标记,然后就是套路了。查询是区间内所有的数的p次幂然后再求和,这个p只有三个值(1,2,3),直接维护三棵线段树,分别是1 2 3次幂。

注意延迟标记的时候,如果有改数,那之前的加法和乘法就可以不用做了。在更新乘法的时候,如果有加法存在,那加法的标记应该更新,乘一下乘法的数,因为(a+b)*c = a*c+b*c,父亲是a+b,儿子是a和b。

pushdown的顺序就是:改数、乘法、加法。三种询问好处理,(a+b)^2和(a+b)^3展开就行了。

这是我做过的比较复杂的线段树了。

 /*
┓┏┓┏┓┃キリキリ♂ mind!
┛┗┛┗┛┃\○/
┓┏┓┏┓┃ /
┛┗┛┗┛┃ノ)
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┃┃┃┃┃┃
┻┻┻┻┻┻
*/
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
using namespace std;
#define fr first
#define sc second
#define cl clear
#define BUG puts("here!!!")
#define W(a) while(a--)
#define pb(a) push_back(a)
#define Rlf(a) scanf("%lf", &a);
#define Rint(a) scanf("%d", &a)
#define Rll(a) scanf("%I64d", &a)
#define Rs(a) scanf("%s", a)
#define Cin(a) cin >> a
#define FRead() freopen("in", "r", stdin)
#define FWrite() freopen("out", "w", stdout)
#define Rep(i, len) for(int i = 0; i < (len); i++)
#define For(i, a, len) for(int i = (a); i < (len); i++)
#define Cls(a) memset((a), 0, sizeof(a))
#define Clr(a, x) memset((a), (x), sizeof(a))
#define Full(a) memset((a), 0x7f7f, sizeof(a))
#define lrt rt << 1
#define rrt rt << 1 | 1
#define pi 3.14159265359
#define RT return
#define lowbit(x) x & (-x)
#define onenum(x) __builtin_popcount(x)
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
typedef pair<string, int> psi;
typedef map<string, int> msi;
typedef vector<int> vi;
typedef vector<LL> vl;
typedef vector<vl> vvl;
typedef vector<bool> vb; inline bool scan_d(int &num) {
char in;bool IsN=false;
in=getchar();
if(in==EOF) return false;
while(in!='-'&&(in<''||in>'')) in=getchar();
if(in=='-'){ IsN=true;num=;}
else num=in-'';
while(in=getchar(),in>=''&&in<=''){
num*=,num+=in-'';
}
if(IsN) num=-num;
return true;
} const int mod = ;
const int maxn = ; LL add[maxn<<], put[maxn<<], mul[maxn<<];
LL sum1[maxn<<], sum2[maxn<<], sum3[maxn<<]; void pushUP(int rt) {
sum1[rt] = (sum1[lrt] + sum1[rrt]) % mod;
sum2[rt] = (sum2[lrt] + sum2[rrt]) % mod;
sum3[rt] = (sum3[lrt] + sum3[rrt]) % mod;
} void pushDOWN(int rt, int m) {
if(put[rt]) {
put[lrt] = put[rrt] = put[rt];
add[lrt] = add[rrt] = ;
mul[lrt] = mul[rrt] = ;
sum1[lrt] = (m - (m >> )) % mod * put[rt] % mod;
sum1[rrt] = (m >> ) % mod * put[rt] % mod;
sum2[lrt] = (m - (m >> )) % mod * put[rt] % mod * put[rt] % mod;
sum2[rrt] = (m >> ) % mod * put[rt] % mod * put[rt] % mod;
sum3[lrt] = (m - (m >> ) % mod) * (put[rt] * put[rt]) % mod * put[rt] % mod % mod;
sum3[rrt] = (m >> ) % mod * put[rt] * put[rt] % mod * put[rt] % mod % mod;
put[rt] = ;
}
if(mul[rt] != ) {
mul[lrt] = mul[lrt] * mul[rt] % mod;
mul[rrt] = mul[rrt] * mul[rt] % mod;
if(add[lrt]) add[lrt] = (add[lrt] * mul[rt]) % mod;
if(add[rrt]) add[rrt] = (add[rrt] * mul[rt]) % mod;
sum1[lrt] = (sum1[lrt] * mul[rt]) % mod;
sum1[rrt] = (sum1[rrt] * mul[rt]) % mod;
sum2[lrt] = (sum2[lrt] * mul[rt]) % mod * mul[rt] % mod;
sum2[rrt] = (sum2[rrt] * mul[rt]) % mod * mul[rt] % mod;
sum3[lrt] = (sum3[lrt] * mul[rt]) % mod * mul[rt] % mod * mul[rt] % mod;
sum3[rrt] = (sum3[rrt] * mul[rt]) % mod * mul[rt] % mod * mul[rt] % mod;
mul[rt] = ;
}
if(add[rt]) {
add[lrt] = (add[lrt] + add[rt]) % mod;
add[rrt] = (add[rrt] + add[rt]) % mod;
sum3[lrt] = (sum3[lrt] + ((add[rt] * add[rt] % mod) * add[rt] % mod * (m - (m >> )) % mod) + * add[rt] * ((sum2[lrt] + sum1[lrt] * add[rt]) % mod)) % mod;
sum3[rrt] = (sum3[rrt] + ((add[rt] * add[rt] % mod) * add[rt] % mod * (m >> ) % mod) + * add[rt] * ((sum2[rrt] + sum1[rrt] * add[rt]) % mod)) % mod;
sum2[lrt] = (sum2[lrt] + ((add[rt] * add[rt] % mod) * (m - (m >> )) % mod) + ( * sum1[lrt] * add[rt] % mod)) % mod;
sum2[rrt] = (sum2[rrt] + (((add[rt] * add[rt] % mod) * (m >> )) % mod) + ( * sum1[rrt] * add[rt] % mod)) % mod;
sum1[lrt] = (sum1[lrt] + (m - (m >> )) * add[rt]) % mod;
sum1[rrt] = (sum1[rrt] + (m >> ) * add[rt]) % mod;
add[rt] = ;
}
} void build(int l, int r, int rt) {
add[rt] = put[rt] = ; mul[rt] = ;
sum1[rt] =sum2[rt] = sum3[rt] = ;
if(l == r) return;
int m = (l + r) >> ;
build(l, m, lrt);
build(m+, r, rrt);
} void update(int L, int R, int c, int ch, int l, int r, int rt) {
if(L <= l && r <= R) {
if(ch == ) {
put[rt] = c;
add[rt] = ;
mul[rt] = ;
sum1[rt] = ((r - l + ) * c) % mod;
sum2[rt] = (((r - l + ) * c) % mod * c) % mod;
sum3[rt] = ((((r - l + ) * c) % mod * c) % mod * c) % mod;
}
if(ch == ) {
mul[rt] = (mul[rt] * c) % mod;
if(add[rt]) add[rt] = (add[rt] * c) % mod;
sum1[rt] = (sum1[rt] * c) % mod;
sum2[rt] = ((sum2[rt] * c) % mod * c) % mod;
sum3[rt] = (((sum3[rt] * c) % mod * c) % mod * c) % mod;
}
if(ch == ) {
add[rt] += c;
sum3[rt] = (sum3[rt] + (((c * c) % mod * c) % mod * (r - l + )) % mod + * c * ((sum2[rt] + sum1[rt] * c) % mod)) % mod;
sum2[rt] = (sum2[rt] + (c * c % mod * (r - l + ) % mod) + * sum1[rt] * c) % mod;
sum1[rt] = (sum1[rt] + (r - l + ) * c) % mod;
}
return;
}
pushDOWN(rt, r-l+);
int m = (l + r) >> ;
if(R <= m) update(L, R, c, ch, l, m, lrt);
else if(L > m) update(L, R, c, ch, m+, r, rrt);
else {
update(L, R, c, ch, l, m, lrt);
update(L, R, c, ch, m+, r, rrt);
}
pushUP(rt);
} LL query(int L, int R, int p, int l, int r, int rt) {
if(L <= l && r <= R) {
if(p == ) return sum1[rt] % mod;
if(p == ) return sum2[rt] % mod;
if(p == ) return sum3[rt] % mod;
}
pushDOWN(rt, r-l+);
int m = (l + r) >> ;
if(R <= m) return query(L, R, p, l, m, lrt);
else if(m < L) return query(L, R, p, m+, r, rrt);
else return (query(L, R, p, l, m, lrt) + query(L, R, p, m+, r, rrt)) % mod;
} int n, m;
int a, b, c, ch; int main() {
// FRead();
while(~scan_d(n) && ~scan_d(m) && n + m) {
build(, n, );
W(m) {
scan_d(ch); scan_d(a); scan_d(b); scan_d(c);
if(ch != ) update(a, b, c, ch, , n, );
else cout << query(a, b, c, , n, ) << endl;
}
}
RT ;
}

[HDOJ4578]Transformation(线段树,多延迟标记)的更多相关文章

  1. FZU 2171(线段树的延迟标记)

    题意:容易理解. 分析:时隔很久,再一次写了一道线段树的代码,之前线段树的题也做了不少,包括各种延迟标记,但是在组队分任务之后,我们队的线段树就交给了另外一个队友在搞, 然后我就一直没去碰线段树的题了 ...

  2. poj 3468 A Simple Problem with Integers 线段树加延迟标记

    A Simple Problem with Integers   Description You have N integers, A1, A2, ... , AN. You need to deal ...

  3. 线段树初步&&lazy标记

    线段树 一.概述: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a, ...

  4. Fast Arrangement (线段树,延迟标志)

    个人心得:线段树的延迟标志确实是减少了很多时间,思想比较简单,但是实现得时候和建立延迟的时候比较麻烦. 按照我的一些理解,就是更新时找到完全覆盖的区间时,更新延迟标志,不再往下更新,但此时父节点啥的都 ...

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

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

  6. 【BZOJ-2892&1171】强袭作战&大sz的游戏 权值线段树+单调队列+标记永久化+DP

    2892: 强袭作战 Time Limit: 50 Sec  Memory Limit: 512 MBSubmit: 45  Solved: 30[Submit][Status][Discuss] D ...

  7. BZOJ 1798 (线段树||分块)的标记合并

    我原来准备做方差的.. 结果发现不会维护两个标记.. 就是操作变成一个 a*x+b ,每次维护a , b 即可 加的时候a=1 ,b=v 乘的时候a=v ,b=0 #include <cstdi ...

  8. POJ 3237 Tree (树链剖分 路径剖分 线段树的lazy标记)

    题目链接:http://poj.org/problem?id=3237 一棵有边权的树,有3种操作. 树链剖分+线段树lazy标记.lazy为0表示没更新区间或者区间更新了2的倍数次,1表示为更新,每 ...

  9. hdu 1828 Picture(线段树 || 普通hash标记)

    http://acm.hdu.edu.cn/showproblem.php?pid=1828 Picture Time Limit: 6000/2000 MS (Java/Others)    Mem ...

  10. poj3468 线段树的懒惰标记

    题目链接:poj3468 题意:给定一段数组,有两种操作,一种是给某段区间加c,另一种是查询一段区间的和 思路:暴力的方法是每次都给这段区间的点加c,查询也遍历一遍区间,复杂度是n*n,肯定过不去,另 ...

随机推荐

  1. C# 实现Oracle中的数据与Excel之间的转换

    最近项目要求实现数据库之间数据在各个数据库之间导入导出,在此做个笔记 1. 将Oracle中的表导入到Excel中,反之亦然  private static readonly string conne ...

  2. SQL Server数据库事务日志序列号(LSN)介绍

    原文:http://blog.csdn.net/tjvictor/article/details/5251463     日志序列编号(LSN)是事务日志里面每条记录的编号. 当你执行一次备份时,一些 ...

  3. angular入门系列教程1

    主题: 一个能够跑起来的页面,神奇的效果,无需一样JS代码! 效果图: 细节: 当然,这里甚至连登陆都没做,只是看到神奇的当输入用户名或者密码的时候,下面的预览区域也会有相应的更改.没有一行的JS代码 ...

  4. 30个实用的Linux find命令示例

    除了在一个目录结构下查找文件这种基本的操作,你还可以用find命令实现一些实用的操作,使你的命令行之旅更加简易. 本文将介绍15种无论是于新手还是老鸟都非常有用的Linux find命令. 首先,在你 ...

  5. 20160729noip模拟赛zld

    首先显然有多少个奇数,就有多少个回文串是最优的(没有奇数时构造一个回文串 然后有了k个“核心”,把剩下的字符顺序安排到这些的两侧,最后最短的回文串长度就是答案 #include<map> ...

  6. 初尝backbone

    backbone的基础知识在此将不再进行介绍.自己后续应该会整理出来,不过今天先把这几天学的成果用一个demo进行展示. 后续可运行demo将会在sinaapp上分享,不过近期在整理sinaapp上d ...

  7. [转载]C# winform登陆框验证码的实现

    验证码技术已愈来愈成熟,从最初的数字.字母.字符.汉字已经到目前的语言,其应用也甚广,之前大多数只有在网站上可以看到,现在在一些客户端软件也经常可见(比如证券相关软件).之前做的一个基于 C# 客户端 ...

  8. sv_target_output dx11

    http://msdn.microsoft.com/en-us/library/windows/desktop/bb509647(v=vs.85).aspx

  9. jQuery+css+div--一些细节详解

    (一).首先.让我们认识一下最基本普通的alert()弹出框!(改变alert()提示弹出框的样式) 我们在写html或是jsp页面的时候,谁都不希望自己精心设计,且非常美观的页面颜色布局被破坏掉吧! ...

  10. android 解析XML方式(一)

    在androd手机中处理xml数据时很常见的事情,通常在不同平台传输数据的时候,我们就可能使用xml,xml是与平台无关的特性,被广泛运用于数据通信中,那么在android中如何解析xml文件数据呢? ...