(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. 【MySql】Mysql ERROR 1067: Invalid default value for ‘date’ 解决

    在给一个表添加字段的时候,忽然发现会报一个date类型的字段的默认值错误,郁闷~ 经过排查,原来是MySQL的配置问题,在wamp下,MySQL 5.7里是没有设置 SQL_MODE 的. 1.my. ...

  2. shopnc路由功能分析

    项目核心文件 core/shopld.php if (!@include(BASE_DATA_PATH.'/config/config.ini.php')) exit('config.ini.php ...

  3. 【Python学习之四】递归与尾递归

    看完廖雪峰老师的教程,感觉尾递归函数是一个相对难点.于是复习一下,思考了一下,发表一些见解,记录一下. 1.递归函数 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数 ...

  4. Voyager的路由

    修改默认的后台登录路由 打开web.php,把prefix值改为你想设置的值,如back: Route::group(['prefix' => 'back'], function () { Vo ...

  5. 地理位置编码geohash学习笔记

    1.geohash及其性质 一种空间索引技术. (1)将二维的经纬度位置数据转换为一维的字符串(基本上hash族的算法都是这样): 其优点在于hash编码后的字符串,可以方便查找和索引,从而减少相似计 ...

  6. Linux 常用命令(三)

    一.less --分页查看文件:方面查阅(编辑)大文件 说明:支持方向键盘和鼠标向上向下浏览 -N 显示行号 二.head --output the first  part of files 默认显示 ...

  7. Spring boot接受json赋值给java对象

    Spring boot接受json赋值给java对象 新建 模板 小书匠 前言 写这个东西,一方面是我自己在做项目的时候,对json的使用还不是十分的熟悉,对spring boot的使用也不是很熟悉, ...

  8. python爬虫基础17-抓包工具使用

    01 抓包工具原理 HTTP 由于HTTP请求是没有加密的,也没有做任何验证,所以抓包工具直接将请求转发即可. HTTPS 由于HTTPS请求,客户端会使用服务端的证书来加密数据,而且会验证服务端是否 ...

  9. Django 惰性机制

    惰性机制:Publisher.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它并不会马上执行sql,而是当调用QuerySet的时候才执行sql ...

  10. Python中re(正则表达式)模块使用方法

    Python中常用的正则表达式处理函数: re.match re.match 尝试从字符串的开始匹配一个模式,如:下面的例子匹配第一个单词. import re text = "JGood ...