bzoj 1798 段乘段加线段树 双懒标记

来源:互联网 发布:淘宝卖的dnf辅助 编辑:程序博客网 时间:2024/05/18 06:53

要求的值时刻保持正确

懒标记为子节点所需的操作

http://www.lydsy.com/JudgeOnline/problem.php?id=1798

#include<iostream>#include<algorithm>#include<iostream>#include<stdio.h>#include<string.h>#include<stdlib.h>#include<vector>#include<queue>#include<cmath>using namespace std;#define ll long long#define inf 0x3f3f3f3f#define maxNode 100010ll n,p,m;ll a[maxNode];struct node{ll l,r;ll sum;//求和值时刻保持正确ll jia,cheng;//标记都是对本点已经进行了标记ll mid(){return (l+r)>>1;}}tree[4*maxNode];void pushdown(ll id){if(tree[id].cheng!=1 || tree[id].jia!=0){tree[id<<1].cheng=tree[id<<1].cheng*tree[id].cheng%p;tree[id<<1].jia=(tree[id<<1].jia*tree[id].cheng%p+tree[id].jia)%p;tree[id<<1|1].cheng=tree[id<<1|1].cheng*tree[id].cheng%p;tree[id<<1|1].jia=(tree[id<<1|1].jia*tree[id].cheng%p+tree[id].jia)%p;ll x=tree[id].l;ll y=tree[id].r;ll mid=tree[id].mid();tree[id<<1].sum=(tree[id<<1].sum*tree[id].cheng%p+tree[id].jia*(mid-x+1)%p)%p;tree[id<<1|1].sum=(tree[id<<1|1].sum*tree[id].cheng%p+tree[id].jia*(y-mid)%p)%p;tree[id].cheng=1;tree[id].jia=0;}}void pushup(ll id){tree[id].sum=(tree[id<<1].sum+tree[id<<1|1].sum)%p;}void build(ll id,ll x,ll y){tree[id].l=x;tree[id].r=y;tree[id].cheng=1;tree[id].jia=0;if(x==y){tree[id].sum=a[x];return;}ll mid=(x+y)>>1;build(id<<1,x,mid);build(id<<1|1,mid+1,y);pushup(id);}void change(ll id,ll x,ll y,ll z,ll kind){if(tree[id].l==x && tree[id].r==y){if(kind==1){tree[id].cheng=tree[id].cheng*z%p;tree[id].jia=tree[id].jia*z%p;tree[id].sum=tree[id].sum*z%p;}else{tree[id].jia=(tree[id].jia+z)%p;tree[id].sum=(tree[id].sum+z*(y-x+1)%p)%p;}return ;}pushdown(id);int mid=tree[id].mid();if(y<=mid) change(id<<1,x,y,z,kind);else if(mid+1<=x) change(id<<1|1,x,y,z,kind);else{change(id<<1,x,mid,z,kind);change(id<<1|1,mid+1,y,z,kind);}pushup(id);}ll query(ll id,ll x,ll y){if(tree[id].l==x && tree[id].r==y){return tree[id].sum;}pushdown(id);int mid=tree[id].mid();if(y<=mid) return query(id<<1,x,y);else if(x>=mid+1) return query(id<<1|1,x,y);else return (query(id<<1,x,mid)+query(id<<1|1,mid+1,y))%p;}int main(){while(scanf("%lld%lld",&n,&p)!=EOF){ll i,j,k;ll ta,tb,tc,td;for(i=1;i<=n;i++)scanf("%lld",&a[i]);build(1,1,n);scanf("%lld",&m);while(m--){scanf("%lld",&ta);if(ta==3){scanf("%lld%lld",&tb,&tc);printf("%lld\n",query(1,tb,tc));}else{scanf("%lld%lld%lld",&tb,&tc,&td);change(1,tb,tc,td,ta);}}}return 0;}


0 0
原创粉丝点击