【BZOJ 1798】维护序列
来源:互联网 发布:淘宝达人直播哪里打开 编辑:程序博客网 时间:2024/06/05 19:32
线段树~
这(D)道(Q)题(S)告诉我说:“你没学过线段树”
嗯……
这题要好好想想……QAQ
来吧
首先要明确的事情是
delta[now]记录的是已经对当前点做过的,但是还没有对当前点的儿子做过的操作
嗯……
我们就这样
慢慢的退一下
嗯
标记是给儿子用的
嗯
是给儿子用的 奉献精神
然后,对于这个题,我们可以把所有操作统一为对该节点*x
+y
的形式 void change(int l,int r,LL add,LL mult,int p)
那么区间乘就成了change(l,r,0,v,1);
那么区间加就成了change(l,r,v,1,1);
标记是什么?
对目前的答案进行标记该有的操作之后会得到真实的答案
真理往往隐蔽在众多表象的茫茫迷雾之中,而标记就像穿透这迷雾的明灯,引导着探索者到达真理的彼岸 (old_ans * mult) + add = new_old
标记的作用是引导儿子走上正轨
所以说下放标记的时候要将儿子的ans计算出来
嗯
然后怎么更新标记
这成了大问题
设
{
a = mult
b = add
change(l,r,d,c,1)
x = 更新之后的mult
y = 更新之后的add
}
为了使得 (sum * a + b) * c + d == sum * x + y
sum * a * c + b * c + d == sum * x + y
x = a * c
y = b * c + d
然后就可以更新了~
嗯
kill
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#define L(x) (x << 1)#define R(x) (x << 1 | 1)#define sz(x) (tree[x].r - tree[x].l + 1)using namespace std;const int MAXN = 100000 + 5;typedef long long LL;int P;struct dot{ int l,r; LL sum,add,mult;}tree[MAXN << 2];int num[MAXN];void update(int p){ tree[p].sum = (tree[L(p)].sum + tree[R(p)].sum) % P; return;}void build(int l,int r,int p){ tree[p].l = l; tree[p].r = r; tree[p].mult = 1; if(l == r) { tree[p].sum = num[l]; return; } int mid = (l + r) >> 1; build(l,mid,L(p)); build(mid + 1,r,R(p)); update(p); return;}void spread(int p){ tree[L(p)].mult = (tree[L(p)].mult * tree[p].mult) % P; tree[L(p)].add = ((tree[L(p)].add * tree[p].mult) % P + tree[p].add % P) % P; tree[L(p)].sum = ((tree[L(p)].sum * tree[p].mult) % P + (tree[p].add * sz(L(p))) % P) % P; tree[R(p)].mult = (tree[R(p)].mult * tree[p].mult) % P; tree[R(p)].add = ((tree[R(p)].add * tree[p].mult) % P + tree[p].add % P) % P; tree[R(p)].sum = ((tree[R(p)].sum * tree[p].mult) % P + (tree[p].add * sz(R(p))) % P) % P; tree[p].add = 0; tree[p].mult = 1; return;}void change(int l,int r,LL add,LL mult,int p){ if(l <= tree[p].l && tree[p].r <= r) { tree[p].mult = (tree[p].mult * mult) % P; tree[p].add = ((tree[p].add * mult) % P + add % P) % P; tree[p].sum = ((tree[p].sum * mult) % P + (add * sz(p)) % P) % P; return; } spread(p); int mid = (tree[p].l + tree[p].r) >> 1; if(l <= mid)change(l,r,add,mult,L(p)); if(mid < r)change(l,r,add,mult,R(p)); update(p); return;}LL ask(int l,int r,int p){ if(l <= tree[p].l && tree[p].r <= r) return tree[p].sum; spread(p); LL ans = 0; int mid = (tree[p].l + tree[p].r) >> 1; if(l <= mid)ans += ask(l,r,L(p)); if(mid < r)ans += ask(l,r,R(p)); return ans;}int n,m;int q,a,b;LL v;int main(){ scanf("%d %lld",&n,&P); for(int i = 1;i <= n;i ++) scanf("%d",&num[i]); build(1,n,1); scanf("%d",&m); for(int i = 1;i <= m;i ++) { scanf("%d",&q); switch(q) { case 1:scanf("%d %d %lld",&a,&b,&v);change(a,b,0ll,v,1);break; case 2:scanf("%d %d %lld",&a,&b,&v);change(a,b,v,1ll,1);break; case 3:scanf("%d %d",&a,&b);printf("%lld\n",ask(a,b,1) % P);break; } } return 0;}
0 0
- 【BZOJ 1798】维护序列
- BZOJ 1798, 维护序列
- 【bzoj 1798】[AHOI2009]维护序列
- BZOJ 1798 维护序列 seq
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq
- BZOJ 1798 Ahoi 2009 维护序列seq
- bzoj 1798: [Ahoi2009]Seq 维护序列seq
- 【BZOJ 1798】 [Ahoi2009]Seq 维护序列seq
- bzoj 1798 [Ahoi2009]Seq 维护序列seq
- 【BZOJ 1798】[Ahoi2009]Seq 维护序列seq
- [BZOJ 1798][Ahoi2009]Seq 维护序列seq
- BZOJ 1798 [Ahoi2009]Seq 维护序列seq
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq
- 【BZOJ】1798 [Ahoi2009]Seq 维护序列seq
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq
- [BZOJ]1798: [Ahoi2009]Seq 维护序列seq
- bzoj 1798 [Ahoi2009]Seq 维护序列seq
- docker pipework 设置网络
- Android异步消息处理机制Handler完全解析
- 浅谈 C++ 中的 new/delete
- 《玫瑰》——贰佰
- 加油!
- 【BZOJ 1798】维护序列
- iOS开发基础控件--标签(UILabel)
- 第一章:HTML基本语法
- JavaScript encodeURI() 函数
- PHP 5 常量
- Python 错误和异常小结
- 使用JS或jQuery模拟鼠标点击a标签事件代码
- Admob for Android不显示
- Android Studio 2.0 beta 7 发布