[bzoj1798][codevs2216][luogu2023][Ahoi2009]维护序列

来源:互联网 发布:vb系列顺序 编辑:程序博客网 时间:2024/06/11 12:11

这线段树我服 写的我都快怀疑人生了

然而思路很简单

假设这个数初始是a 那么*x之后是ax

再加c ax+c

再乘p

(axp+cp)

以此类推

关键是实现异常困难 这里先放代码和重要的部分 还没来得及加注释

感谢Flere825神犇的指导

关键点在push_down处 以后再看这篇文章的时候一定要用心理解

#include<cstdio>#include<iostream>#include<cstdlib>#include<algorithm>#include<cstring>#include<cmath>#include<map>#include<set>#define lson (now<<1)#define rson lson+1#define mid ((l+r)>>1)using namespace std;int n,q;long long model;struct segment{int l,r;long long val;long long lazy;long long mut;}tree[200000<<2];long long a[200001];void update(int now){tree[now].val=(tree[lson].val+tree[rson].val)%model;}inline long long init(){int ju=1;long long now=0;char c;bool flag=false;while(1){c=getchar();if(c=='-'){ju=-1;}else if(c>='0'&&c<='9'){now=now*10+c-'0';flag=true;}else if(flag)return now*ju;}}inline int read(){int ju=1;int now=0;char c;bool flag=false;while(1){c=getchar();if(c=='-'){ju=-1;}else if(c>='0'&&c<='9'){now=now*10+c-'0';flag=true;}else if(flag)return now*ju;}}void push_down(int now){tree[lson].mut=(tree[lson].mut*tree[now].mut)%model;tree[lson].lazy=(((tree[lson].lazy*tree[now].mut)%model)+(tree[now].lazy%model))%model;tree[rson].mut=(tree[rson].mut*tree[now].mut)%model;tree[rson].lazy=(((tree[rson].lazy*tree[now].mut)%model)+(tree[now].lazy%model))%model;tree[lson].val=(tree[lson].val*tree[now].mut)%model;tree[lson].val=((tree[lson].val)+((tree[lson].r-tree[lson].l+1)*tree[now].lazy))%model;tree[rson].val=(tree[rson].val*tree[now].mut)%model;tree[rson].val=((tree[rson].val)+((tree[rson].r-tree[rson].l+1)*tree[now].lazy))%model;tree[now].lazy=0;tree[now].mut=1;}void add(int now,int l,int r,int x,int y,int delta){push_down(now);if(x==l&&r==y){tree[now].val+=(tree[now].r-tree[now].l+1)*delta;tree[now].val%=model;tree[now].lazy=(delta+tree[now].lazy)%model;}else{if(y<=mid)add(lson,l,mid,x,y,delta);else if(x>mid)add(rson,mid+1,r,x,y,delta);else add(lson,l,mid,x,mid,delta),add(rson,mid+1,r,mid+1,y,delta);update(now);}}void muti(int now,int l,int r,int x,int y,int delta){push_down(now);if(x==l&&r==y){tree[now].val=tree[now].val*delta;tree[now].val%=model;tree[now].mut=(tree[now].mut*delta)%model;}else{if(y<=mid)muti(lson,l,mid,x,y,delta);else if(x>mid)muti(rson,mid+1,r,x,y,delta);else muti(lson,l,mid,x,mid,delta),muti(rson,mid+1,r,mid+1,y,delta);update(now);}}long long query(int now,int x,int y,int l,int r){push_down(now);if(x==l&&r==y){return (tree[now].val)%model;}else{if(y<=mid){return ((query(lson,x,y,l,mid))%model);}else if(x>mid){if(x>mid)return ((query(rson,x,y,mid+1,r))%model);}else return ((((query(lson,x,mid,l,mid))%model)+((query(rson,mid+1,y,mid+1,r)))%model));}}void build(int now,int l,int r){tree[now].l=l;tree[now].r=r;tree[now].mut=1;if(l==r){tree[now].val=a[l]%model;}else{build(lson,l,mid);build(rson,mid+1,r);update(now);}}int main(){n=read();model=init();for(int i=1;i<=n;i++){a[i]=init();}build(1,1,n);q=read();int type;int tmpa,tmpb;long long tmpc;for(int i=1;i<=q;i++){type=read();if(type==1){tmpa=read();tmpb=read();tmpc=init();muti(1,1,n,tmpa,tmpb,tmpc);}if(type==2){tmpa=read();tmpb=read();tmpc=init();add(1,1,n,tmpa,tmpb,tmpc);}if(type==3){tmpa=read();tmpb=read();printf("%lld\n",(query(1,tmpa,tmpb,1,n))%model);}}return 0;}

本题这样打其实是很暴力的

可以处理掉一步 大概能优化20%

tree[lson].lazy=((tree[lson].lazy*tree[now].mut)+(tree[now].lazy))%model;tree[rson].mut=(tree[rson].mut*tree[now].mut)%model;tree[rson].lazy=((tree[rson].lazy*tree[now].mut)+(tree[now].lazy))%model;

由于lazy一般不大 而且是longlong 所以一般能过


0 0
原创粉丝点击