[HDOJ4578]Transformation(线段树,多延迟标记)
题目链接: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(线段树,多延迟标记)的更多相关文章
- FZU 2171(线段树的延迟标记)
题意:容易理解. 分析:时隔很久,再一次写了一道线段树的代码,之前线段树的题也做了不少,包括各种延迟标记,但是在组队分任务之后,我们队的线段树就交给了另外一个队友在搞, 然后我就一直没去碰线段树的题了 ...
- poj 3468 A Simple Problem with Integers 线段树加延迟标记
A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal ...
- 线段树初步&&lazy标记
线段树 一.概述: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a, ...
- Fast Arrangement (线段树,延迟标志)
个人心得:线段树的延迟标志确实是减少了很多时间,思想比较简单,但是实现得时候和建立延迟的时候比较麻烦. 按照我的一些理解,就是更新时找到完全覆盖的区间时,更新延迟标志,不再往下更新,但此时父节点啥的都 ...
- HDU 4578 Transformation --线段树,好题
题意: 给一个序列,初始全为0,然后有4种操作: 1. 给区间[L,R]所有值+c 2.给区间[L,R]所有值乘c 3.设置区间[L,R]所有值为c 4.查询[L,R]的p次方和(1<=p< ...
- 【BZOJ-2892&1171】强袭作战&大sz的游戏 权值线段树+单调队列+标记永久化+DP
2892: 强袭作战 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 45 Solved: 30[Submit][Status][Discuss] D ...
- BZOJ 1798 (线段树||分块)的标记合并
我原来准备做方差的.. 结果发现不会维护两个标记.. 就是操作变成一个 a*x+b ,每次维护a , b 即可 加的时候a=1 ,b=v 乘的时候a=v ,b=0 #include <cstdi ...
- POJ 3237 Tree (树链剖分 路径剖分 线段树的lazy标记)
题目链接:http://poj.org/problem?id=3237 一棵有边权的树,有3种操作. 树链剖分+线段树lazy标记.lazy为0表示没更新区间或者区间更新了2的倍数次,1表示为更新,每 ...
- hdu 1828 Picture(线段树 || 普通hash标记)
http://acm.hdu.edu.cn/showproblem.php?pid=1828 Picture Time Limit: 6000/2000 MS (Java/Others) Mem ...
- poj3468 线段树的懒惰标记
题目链接:poj3468 题意:给定一段数组,有两种操作,一种是给某段区间加c,另一种是查询一段区间的和 思路:暴力的方法是每次都给这段区间的点加c,查询也遍历一遍区间,复杂度是n*n,肯定过不去,另 ...
随机推荐
- backup site collection
http://stackoverflow.com/questions/5376380/sharepoint-2010-change-sitecollection-urlstsadm -o backup ...
- Team Homework #3: The feedback of predecessors
此次对学长的采访主要在QQ上进行,感谢陈宇宁学长的热情配合. 采访学长的问题及学长的答复如下: 1. 平均每周花在这门课上的时间 (包括上课/作业/上机) -大约15-20小时吧(学长个人花费时间) ...
- 文件中的类都不能进行设计,因此未能为该文件显示设计器。设计器检查出文件中有以下类: FormMain --- 未能加载基类“WinForm.Win.FormsBase.FormMainBase”。请确保已引用该程序集并已生成所有项目
出现该问题的原因:FormMain从FormMainBase继承之后,一旦修改FormMainBase就会出现这个问题 解决方案:(1-4是搜索网友的) 1: 关闭VS所有窗口,后重启.即可返回正常. ...
- mysql innodb 引擎
innodb 引擎 一.概述 InnoDB 是一个用的比较广泛的存储引擎,因为它支持事物和外键,还有不错的效率;我们先看看官方教程怎么说; 我们先读一下, 对于上面的文档, 对一个InnoDB的表首先 ...
- apache + tomcat 集群
apache2.2与tomcat集成(可以多个tomcat) 需求概况: 有3个服务: localhost:9091, localhost:9190. localhost:9191分别对应3个tomc ...
- tomcat服务
参考资料:http://www.chysoft.net/showinfo.asp?id=84 (1) Tomcat服务的安装 说明: 默认情况下,tomcat的服务是未安装的,具体tomcat服务的安 ...
- 【HDOJ】【1512】Monkey King
数据结构/可并堆 啊……换换脑子就看了看数据结构……看了一下左偏树和斜堆,鉴于左偏树不像斜堆可能退化就写了个左偏树. 左偏树介绍:http://www.cnblogs.com/crazyac/arti ...
- failed creating the Direct3d device--debug
D3DDEVTYPE_REF 使用REF设备,用软件模拟Direct3D API 照理说是为了让电脑能跑本机不能硬件执行的渲染命令的 但我 pDeviceSettings->d3d9.Devic ...
- 【WCF--初入江湖】05 WCF异步编程
05 WCF异步编程 一.服务设计最佳实践 在设计之初,是否用异步,应该由客户端来决定,而不应该去考虑服务的调用者调用的方式. 优点:充分利用多核CPU, 改善用户体验 缺点:滥用异步,会影响性能 二 ...
- LoadAssetAtPath 与 Load 的区别
一.官方的文档 Resources.LoadAssetAtPath Returns a resource at an asset path (Editor Only). This function a ...