(1)"1 x y c",代表 把区间 [x,y] 上的值全部加c

(2)"2 x y c",代表 把区间 [x,y] 上的值全部乘以c

(3)"3 x y c" 代表 把区间 [x,y]上的值全部赋值为c

(4)"4 x y p" 代表 求区间 [x,y] 上值的p次方和1<=p<=3

维护sum1[], sum2[], sum3[]分别为一次方、二次方、三次方的和

因为P只有1到3,(x+c)^2=(x^2)+(2*x*c+c^2),即我们可以从一次方和的结果推出二次方的和的结果。同理,我们也可以根据一次方的和的结果,二次方和的结果推出三次方和的结果。这样,我们可以用几个懒标记去记录这几个操作。但是这题明白上面这点还是不够的,因为,这几种更新操作之间会相互影响,比如对一个区间进行操作3之后,那么操作1和2就失效了。因此在PushDown传递懒标记的时候,传递的顺序也是重要的。

 #include <bits/stdc++.h>
#include <string.h>
#include <iostream>
#include <stdio.h>
#define pb push_back
#define fi first
#define se second
#define lson(r) (r<<1)
#define rson(r) ((r<<1)|1) using namespace std; typedef long long ll; const int MAXN = 1e5+;
const int MAXV = ;
const int MAXE = ;
const ll MOD = ;
ll sum1[MAXN << ];
ll sum2[MAXN << ];
ll sum3[MAXN << ];
ll addmark[MAXN << ];
ll setmark[MAXN << ];
ll mulmark[MAXN << ]; void pushDown(int root, int l, int r)
{
int num = (r-l+);
ll numr = num >> ;
ll numl = num - numr;
//思考了半天用-1还是不够优秀呀 只需要把另外优先级低的懒标记 标记的左右子即可
//修改了半天 哎哎哎 这道题目深入理解懒标记
if (setmark[root])
{
ll setval = setmark[root];
//cout << "set" << l << " " << r << " " << setmark[root] << endl;
sum1[lson(root)] = (numl*setval) % MOD;
sum1[rson(root)] = (numr*setval) % MOD;
sum2[lson(root)] = (numl*setval*setval) % MOD;
sum2[rson(root)] = (numr*setval*setval) % MOD;
sum3[lson(root)] = (numl*setval*setval*setval) % MOD;
sum3[rson(root)] = (numr*setval*setval*setval) % MOD;
setmark[lson(root)] = setval;
setmark[rson(root)] = setval;
addmark[lson(root)] = addmark[rson(root)] = ;
mulmark[lson(root)] = mulmark[rson(root)] = ;
setmark[root] = ;
}
if (mulmark[root] != )
{
ll mulval = mulmark[root];
sum1[lson(root)] = (sum1[lson(root)]*mulval) % MOD;
sum1[rson(root)] = (sum1[rson(root)]*mulval) % MOD;
sum2[lson(root)] = (sum2[lson(root)]*mulval*mulval) % MOD;
sum2[rson(root)] = (sum2[rson(root)]*mulval*mulval) % MOD;
sum3[lson(root)] = (sum3[lson(root)]*mulval*mulval*mulval) % MOD;
sum3[rson(root)] = (sum3[rson(root)]*mulval*mulval*mulval) % MOD;
mulmark[lson(root)] = (mulmark[lson(root)]*mulval) % MOD;
mulmark[rson(root)] = (mulmark[rson(root)]*mulval) % MOD;
addmark[lson(root)] = (addmark[lson(root)]*mulval) % MOD;
addmark[rson(root)] = (addmark[rson(root)]*mulval) % MOD;
mulmark[root] = ;
}
if (addmark[root])
{
ll addval = addmark[root];
sum3[lson(root)] = ((sum3[lson(root)]+numl*addval*addval*addval)%MOD+(*sum2[lson(root)]*addval+*sum1[lson(root)]*addval*addval)%MOD)%MOD;
sum3[rson(root)] = ((sum3[rson(root)]+numr*addval*addval*addval)%MOD+(*sum2[rson(root)]*addval+*sum1[rson(root)]*addval*addval)%MOD)%MOD;
sum2[lson(root)] = (((sum2[lson(root)] + numl*addval*addval) % MOD) + (*sum1[lson(root)]*addval)) % MOD;
sum2[rson(root)] = (((sum2[rson(root)] + numr*addval*addval) % MOD) + (*sum1[rson(root)]*addval)) % MOD;
sum1[lson(root)] = (sum1[lson(root)] + numl * addval) % MOD;
sum1[rson(root)] = (sum1[rson(root)] + numr * addval) % MOD;
addmark[lson(root)] = (addmark[lson(root)] + addval) % MOD;
addmark[rson(root)] = (addmark[rson(root)] + addval) % MOD;
addmark[root] = ;
}
}
void update(int root, int l, int r, int ul, int ur, int mathod, ll val)
{
if (l > ur || r < ul) return ;
if (l >= ul && r <= ur)
{
ll num = r-l+;
if (mathod == )
{
//cout << l << " " << r << " " << val << endl;
setmark[root] = val%MOD;
addmark[root] = ;
mulmark[root] = ;
sum1[root] = (num*val) % MOD;
sum2[root] = (num*val*val) % MOD;
sum3[root] = (num*val*val*val) % MOD;
}
else if (mathod == )
{
mulmark[root] = (mulmark[root]*val)%MOD;
addmark[root] = (val*addmark[root])%MOD;
sum1[root] = (sum1[root]*val) % MOD;
sum2[root] = (sum2[root]*val*val) % MOD;
sum3[root] = (sum3[root]*val*val*val) % MOD;
}
else if (mathod == )
{ //cout << l << " " << r << " " << sum1[root] << endl;
addmark[root] = (addmark[root]+val)%MOD;
sum3[root] = ((sum3[root]+num*val*val*val)%MOD+(*sum2[root]*val+*sum1[root]*val*val)%MOD)%MOD;
sum2[root] = ((sum2[root] + num*val*val) % MOD + (*sum1[root]*val)) % MOD;
sum1[root] = (sum1[root] + num * val) % MOD;
//cout << l << " " << r << " " << sum1[root] << endl;
}
return ;
}
pushDown(root, l, r);
int mid = (l+r) >> ;
if (ul <= mid) update(lson(root), l, mid, ul, ur, mathod, val);
if (ur > mid) update(rson(root), mid+, r, ul, ur, mathod, val);
sum1[root] = (sum1[lson(root)] + sum1[rson(root)]) % MOD;
sum2[root] = (sum2[lson(root)] + sum2[rson(root)]) % MOD;
sum3[root] = (sum3[lson(root)] + sum3[rson(root)]) % MOD;
//cout << l << " " << r << " " << sum1[root] << endl;
} int cnt = ;
ll query(int root, int l, int r, int ql, int qr, int p)
{
// cout << l << " " << r << endl;
if (l > qr || r < ql) return ;
if (l >= ql && r <= qr)
{
if (p == ) return sum1[root];
else if (p == ) return sum2[root];
else if (p == ) return sum3[root];
}
pushDown(root, l, r);
int mid = (l+r) >> ;
ll res = ;
if (ql <= mid) res = (res + query(lson(root), l, mid, ql, qr, p)) % MOD;
if (qr >= mid+) res = (res + query(rson(root), mid+, r, ql, qr, p)) % MOD;
return res;
}
int n, m;
int main()
{
// freopen("in.txt", "r", stdin);
while (~scanf("%d%d", &n, &m))
{
for(int i = ; i < MAXN << ; i++) mulmark[i] = ;
if (!n && !m) break;
memset(addmark, , sizeof(addmark));
//memset(mulmark, 1, sizeof(mulmark));
memset(setmark, , sizeof(setmark));
memset(sum1, , sizeof(sum1));
memset(sum2, , sizeof(sum2));
memset(sum3, , sizeof(sum3));
for (int i = ; i < m; i++)
{
int op, l, r, c;
scanf("%d%d%d%d", &op, &l, &r, &c);
if (op == )
{
update(, , n, l, r, , c);
}
else if (op == )
{
update(, , n, l, r, , c);
}
else if (op == )
{
update(, , n, l, r, , c);
}
else
{
ll ans = query(, , n, l, r, c);
cout << ans << endl;
}
}
}
return ;
}

线段树懒标记好题 HDU4578的更多相关文章

  1. 「雅礼集训 2017 Day2」线段游戏(线段树懒标记“启发式下传”,李超树)

    题面 题解 加入一条线段,可以把它转化为在[L,R]区间内加一条线 y=ax+b (如果原线段与y轴平行,就相当于在{x1}处加一条线 y=max(y1,y2)) 我们可以把它加到线段树上,线段树上每 ...

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

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

  3. GSS4 - Can you answer these queries IV(线段树懒操作)

    GSS4 - Can you answer these queries IV(线段树懒操作) 标签: 线段树 题目链接 Description recursion有一个正整数序列a[n].现在recu ...

  4. Codeforces 258E - Little Elephant and Tree(根号暴力/线段树+标记永久化/主席树+标记永久化/普通线段树/可撤销线段树,hot tea)

    Codeforces 题目传送门 & 洛谷题目传送门 yyq:"hot tea 不常有,做过了就不能再错过了" 似乎这是半年前某场 hb 模拟赛的 T2?当时 ycx.ym ...

  5. poj 3264:Balanced Lineup(线段树,经典题)

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 32820   Accepted: 15447 ...

  6. hdu 1754:I Hate It(线段树,入门题,RMQ问题)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  7. hdu 4578 线段树(标记处理)

    Transformation Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others) ...

  8. hdu 3954 线段树 (标记)

    Level up Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  9. BZOJ4785 [Zjoi2017]树状数组 【二维线段树 + 标记永久化】

    题目链接 BZOJ4785 题解 肝了一个下午QAQ没写过二维线段树还是很难受 首先题目中的树状数组实际维护的是后缀和,这一点凭分析或经验或手模观察可以得出 在\(\mod 2\)意义下,我们实际求出 ...

随机推荐

  1. java static block

    java 中 静态块的作用 (一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在 ...

  2. java基础——反射机制

    反射机制是什么 反射机制就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...

  3. 深入理解ES6箭头函数的this以及各类this面试题总结

    ES6中新增了箭头函数这种语法,箭头函数以其简洁性和方便获取this的特性,俘获了大批粉丝儿 它也可能是面试中的宠儿, 我们关键要搞清楚 箭头函数和普通函数中的this 一针见血式总结: 普通函数中的 ...

  4. cnpm 莫名奇妙bug 莫名奇妙的痛

    cnpm 莫名奇妙bug 莫名奇妙的痛 最近想搭建react@v16 和 react-router@v4,搭建过程打算用vue脚手架webpack模板那套配置方法(webpack3). 由于我之前安装 ...

  5. errno的用法

    Linux中系统调用的错误都存储于 errno中,errno由操作系统维护,存储就近发生的错误,即下一次的错误码会覆盖掉上一次的错误. 编程时需要包含#include <errno.h>, ...

  6. 【最大权闭合子图 tarjan】bzoj1565: [NOI2009]植物大战僵尸

    dinic+tarjan板子练手题 Description Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其 中P ...

  7. 根据参数优化nginx的服务性能

    一.优化nginx服务的worker进程数 在高并发.高访问量的Web服务场景,需要事先启动好更多的nginx进程,以保证快速响应并处理大量并发用户的请求. 1).优化nginx进程对应的配置 优化n ...

  8. POJ:1094-Sorting It All Out(拓扑排序经典题型)

    Sorting It All Out Time Limit: 1000MS Memory Limit: 10000K Description An ascending sorted sequence ...

  9. Linux学习-循环执行的例行性工作排程

    循环执行的例行性工作排程则是由 cron (crond) 这个系统服务来控制的.Linux 系统上面原本就有非常多的例行性工作,因此这个系统服务是默认启动的. 另外, 由于使用者自己也可以进行例行性工 ...

  10. SPOJ COT2 Count on a tree II 树上莫队算法

    题意: 给出一棵\(n(n \leq 4 \times 10^4)\)个节点的树,每个节点上有个权值,和\(m(m \leq 10^5)\)个询问. 每次询问路径\(u \to v\)上有多少个权值不 ...