bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树

来源:互联网 发布:安卓应用程序源码 编辑:程序博客网 时间:2024/05/16 11:20

→题目链接←


【想说的话】

又是一道题解泛滥的题


【题解】

裸线段树,注意乘的时候加的标记也要乘,传标记时要乘一下

看代码吧...


【代码】

#include<bits/stdc++.h>#define inf 1000000000#define MAXN 100005typedef long long ll;using namespace std;inline int rd(){int x=0,y=1;char c=getchar();while(c<'0' || c>'9'){if(c=='-')y=-y;c=getchar();}while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return x*y;}struct node{int l,r,len,mid;ll sum,mul,add;}tree[MAXN*4];int n,mod,ans,num;void push_up(int x){tree[x].sum=(tree[x*2].sum+tree[x*2+1].sum)%mod;}void build(int x,int l,int r){tree[x].l=l;tree[x].r=r;tree[x].len=r-l+1;tree[x].mid=(l+r)/2;tree[x].add=0;tree[x].mul=1;if(l==r){tree[x].sum=rd();return;}build(x*2,l,tree[x].mid);build(x*2+1,tree[x].mid+1,r);push_up(x);}void push_down(int x){tree[x*2].add=(tree[x*2].add*tree[x].mul+tree[x].add)%mod;tree[x*2+1].add=(tree[x*2+1].add*tree[x].mul+tree[x].add)%mod;tree[x*2].mul=tree[x*2].mul*tree[x].mul%mod;tree[x*2+1].mul=tree[x*2+1].mul*tree[x].mul%mod;tree[x*2].sum=(tree[x*2].sum*tree[x].mul%mod+tree[x].add*tree[x*2].len%mod)%mod;tree[x*2+1].sum=(tree[x*2+1].sum*tree[x].mul%mod+tree[x].add*tree[x*2+1].len%mod)%mod;tree[x].mul=1;tree[x].add=0;}ll query(int x,int l,int r){if(tree[x].l>=l && tree[x].r<=r){return tree[x].sum%mod;}push_down(x);if(r<=tree[x].mid)return query(x*2,l,r);else if(l>tree[x].mid)return query(x*2+1,l,r);else return (query(x*2,l,tree[x].mid)+query(x*2+1,tree[x].mid+1,r))%mod;}void update(int x,int l,int r,int k){if(tree[x].l>=l && tree[x].r<=r){if(k==1){tree[x].add=tree[x].add*num%mod;tree[x].mul=tree[x].mul*num%mod;tree[x].sum=tree[x].sum*num%mod;}else{tree[x].add=(tree[x].add+num)%mod;tree[x].sum=(tree[x].sum+(ll)num*tree[x].len%mod)%mod;}return;}push_down(x);if(r<=tree[x].mid)update(x*2,l,r,k);else if(l>tree[x].mid)update(x*2+1,l,r,k);else update(x*2,l,tree[x].mid,k),update(x*2+1,tree[x].mid+1,r,k);push_up(x);}int main(){n=rd(),mod=rd();build(1,1,n);int m=rd();while(m--){int x=rd(),y=rd(),z=rd();if(x==3)printf("%lld\n",query(1,y,z));else{num=rd();update(1,y,z,x);}}return 0;}