hdu4578Transformation(线段树多个lz标记)
这里以3次方来举例讲一下这题的做法,其它维类似。
如果要求某一个值的3次方那么sum = t^3,设t = x+y。那也就是sum = (x+y)^3.
假如我让每个数都加z t = x+y+z,我可以让新的y = y+z,这里发现新来的总会加在y上,那么可以给他一个延迟,slz,
那么新的值t = t + slz,再看如果让每个数都乘k,t = (x+y)*k = xk+yk.可以看出刚才的slz = slz*k; 另外发现系数会跟着变换,可以给他一个延迟,mlz。
那么一个数t = (mlz*x+slz)^3 = mlz^3*x^3+2*mlz^2*slz*x^2+2*mlz*slz^2*x+x^3.
如果求一段这样的和的话,会发现整体就是k1*原本x^3的和+k2*原本x^2的和+k1原本x^1的和 +(r-l+1)*x^3;
这样就可以分别保存3维的和。
把某一段的值设置为v的时候,可以使mlz =0 slz = v.
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 100000
#define LL __int64
#define INF 0xfffffff
const double eps = 1e-;
const double pi = acos(-1.0);
const double inf = ~0u>>;
const int mod = ;
int slz[N<<],mlz[N<<];//lz[N<<2];
LL s[N<<][];
int p[][];
void init()
{
int i,j;
for(i = ; i <= ; i++)
{
p[i][] = i;
for(j = ; j <= ; j++)
p[i][j] = (p[i][j-]*i)%mod;
}
}
void up(int w)
{
for(int i = ; i <= ; i++)
s[w][i] = (s[w<<][i]+s[w<<|][i])%mod;
}
void build(int l,int r,int w)
{
mlz[w] = ;
slz[w] = ;
//lz[w] = 0;
if(l==r)
{
for(int i = ; i <= ; i++)
s[w][i] = ;
return ;
}
int m = (l+r)>>;
build(l,m,w<<);
build(m+,r,w<<|);
up(w);
}
void down(int w,int m)
{ if(mlz[w]!=||slz[w]!=)
{
mlz[w<<] = (mlz[w<<]*mlz[w])%mod;
slz[w<<] = (mlz[w]*slz[w<<]+slz[w])%mod;
mlz[w<<|] = (mlz[w<<|]*mlz[w])%mod;
slz[w<<|] = (mlz[w]*slz[w<<|]+slz[w])%mod; int x1 ,x2,x3,y1,y2,y3;
x1 = mlz[w]; y1 = slz[w];
x2 = p[x1][]; y2 = p[y1][];
x3 = p[x1][]; y3 = p[y1][];
s[w<<][] = (x3*s[w<<][]+(*x2*y1)%mod*s[w<<][]+(*x1*y2)%mod*s[w<<][]+y3*(m-m/))%mod;
s[w<<|][] = (x3*s[w<<|][]+(*x2*y1)%mod*s[w<<|][]+(*x1*y2)%mod*s[w<<|][]+y3*(m/))%mod;
s[w<<][] = (x2*s[w<<][]+(*x1*y1)%mod*s[w<<][]+y2*(m-m/))%mod;
s[w<<|][] = (x2*s[w<<|][]+(*x1*y1)%mod*s[w<<|][]+y2*(m/))%mod;
s[w<<][] = (x1*s[w<<][]+y1*(m-m/))%mod;
s[w<<|][] = (x1*s[w<<|][]+y1*(m/))%mod;
mlz[w] = ;
slz[w] = ;
}
}
void update(int f,int c,int a,int b,int l,int r,int w)
{
if(a<=l&&b>=r)
{
if(f==)
{ mlz[w] = ;
slz[w] = c;
for(int i = ; i <= ; i++)
s[w][i] = (p[c][i]*(r-l+))%mod; }
else if(f==)
{ slz[w]=(slz[w]+c)%mod;
s[w][] = ((s[w][]+*s[w][]*c+*s[w][]*c*c)%mod+(LL)c*c*c*(r-l+))%mod;
s[w][] = ((s[w][]+*c*s[w][])%mod+(LL)c*c*(r-l+))%mod;
s[w][] = s[w][]+c*(r-l+); s[w][]%=mod;
}
else if(f==)
{ mlz[w] *= c;mlz[w]%=mod;
slz[w] *= c;slz[w]%=mod;
// }
//cout<<l<<" "<<r<<" "<<s[w][2]<<endl;
s[w][] = (s[w][]*c*c*c)%mod;
s[w][] = (s[w][]*c*c)%mod;
s[w][] = (c*s[w][])%mod;
//cout<<l<<" "<<r<<" "<<s[w][2]<<endl;
}
return ;
}
down(w,r-l+);
int m = (l+r)>>;
if(a<=m)
update(f,c,a,b,l,m,w<<);
if(b>m) update(f,c,a,b,m+,r,w<<|);
up(w);
}
LL query(int f,int a,int b,int l,int r,int w)
{
if(a<=l&&b>=r)
{
return s[w][f];
}
down(w,r-l+);
int m = (l+r)>>;
LL res=;
if(a<=m) res+=query(f,a,b,l,m,w<<);
res%=mod;
if(b>m) res+=query(f,a,b,m+,r,w<<|);
res%=mod;
return res;
}
int main()
{
int n,m,i;
int k,x,y,c;
init();
while(scanf("%d%d",&n,&m)&&n&&m)
{
build(,n,);
for(i = ;i <= m; i++)
{
scanf("%d%d%d%d",&k,&x,&y,&c);
if(k<=)
update(k,c,x,y,,n,);
else
printf("%I64d\n",(query(c,x,y,,n,))%mod);
}
}
return ;
}
hdu4578Transformation(线段树多个lz标记)的更多相关文章
- 【HDU 4614】Vases and Flowers(线段树区间更新懒惰标记)
题目0到n-1的花瓶,操作1在下标a开始插b朵花,输出始末下标.操作2清空[a,b]的花瓶,求清除的花的数量.线段树懒惰标记来更新区间.操作1,先查询0到a-1有num个空瓶子,然后用线段树的性质,或 ...
- 【BZOJ-4636】蒟蒻的数列 动态开点线段树 ||(离散化) + 标记永久化
4636: 蒟蒻的数列 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 247 Solved: 113[Submit][Status][Discuss ...
- [HDOJ4578]Transformation(线段树,多延迟标记)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578 四种操作:查询.加法.乘法.改数.应该是需要维护三个lazy标记,然后就是套路了.查询是区间内所 ...
- 扶桑号战列舰 (单调栈+线段树区间更新懒惰标记 or 栈)
传送门 •题目描述 题目描述 众所周知,一战过后,在世界列强建造超无畏级战列舰的竞争之中,旧日本海军根据“个舰优越主义”,建造了扶桑级战列舰,完工时为当时世界上武装最为强大的舰只. 同时,扶桑号战列舰 ...
- 杭电 HDU ACM 1698 Just a Hook(线段树 区间更新 延迟标记)
欢迎"热爱编程"的高考少年--报考杭州电子科技大学计算机学院 Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memor ...
- HDU 3911 Black And White (线段树区间合并 + lazy标记)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3911 给你n个数0和1,m个操作: 0操作 输出l到r之间最长的连续1的个数 1操作 将l到r之间 ...
- FZU-1608 Huge Mission 线段树(更新懒惰标记)
题目链接: https://cn.vjudge.net/problem/FZU-1608 题目大意: 长度n,m次操作:每次操作都有三个数:a,b,c:意味着(a,b]区间单位长度的价值为c,若某段长 ...
- HDU 4553 约会安排(线段树区间合并+双重标记)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4553 题目大意:就是有三种操作: ①DS x,安排一段长度为x的空闲时间跟屌丝一起,输出这段时间的起点 ...
- hdu1698 Just a Hook (线段树区间更新 懒惰标记)
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
随机推荐
- Python: PS 滤镜--旋转模糊
本文用 Python 实现 PS 滤镜中的旋转模糊,具体的算法原理和效果可以参考之前的博客: http://blog.csdn.net/matrix_space/article/details/392 ...
- python pickle/cPickle模块
序列化(picking): 把变量从内存中变成可存储或传输的过程称为序列化,序列化之后,就可以把序列化的对象写入磁盘,或者传输给其他设备; 反序列化(unpickling):相应的,把变量的内容从序列 ...
- 如何判断一个for循环执行完毕
在外面一个变量a=arr.leng; 然后就是进行for循环, 在for循环下面进行判断,因为如果结束那么i的值就会>=a;if条件成立的话,可以在里面进行循环完毕要做的操作.
- 操作 AutoIT:界面与自动化操作结合来简化日常劳动: .Net Reactor验证License,设置License,创建License,截图AutoIt自动化实现。(六)
自动化操作的稳定性,便利性虽然已经满足了要求,但是页面上呈现的按钮太多了,可以做的更加简单一些. 1. 简化页面的按钮,把5个按钮减少至3个,把Display HID按钮功能整合到create lic ...
- MongoDB:搭建三节点 Replica Set 环境
今天学习了搭建 MongDB 复制环境,实验环境是在虚拟机上同一系统,并搭建三节点 Replica Set,根据文档上的描述,mongodb 复制配置简单,并且能够自动 failover,这些高级特性 ...
- POJ1741:Tree
浅谈树分治:https://www.cnblogs.com/AKMer/p/10014803.html 题目传送门:http://poj.org/problem?id=1741 这是一道树分治的模板题 ...
- HDU acm1028 整数划分 递归问题(递推)
我们用递归+记忆化的方法来解决普通整数划分问题:定义 f(n,m)为将整数n划分为一系列整数之和,其中加数 最大不超过m. 得到下面的递推关系式: 当n==1 || m==1 只有一种划分,即 1 或 ...
- 《Linux内核修炼之道》精华分享与讨论(5)——Kernel地图:Kconfig与Makefile
转自:http://blog.csdn.net/fudan_abc/article/details/5340408 Makefile不是Make Love 从前在学校,混了四年,没有学到任何东西,每天 ...
- CF-807A
A. Is it rated? time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...
- Asset Catalog Help (八)---Customizing Image Sets for Devices
Customizing Image Sets for Devices Add images to a set that are customized for display on the device ...