zoukankan      html  css  js  c++  java
  • BZOJ1798:[AHOI2009]维护序列

    浅谈树状数组与线段树:https://www.cnblogs.com/AKMer/p/9946944.html

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1798

    线段树区间加区间乘区间询问裸题。因为乘标记会影响加标记,所以优先下传乘标记。

    时间复杂度:(O(mlogn))

    空间复杂度:(O(n))

    代码如下:

    #include <cstdio>
    using namespace std;
    
    const int maxn=1e5+5;
    
    int n,m,pps;
    int a[maxn];
    
    int read() {
    	int x=0,f=1;char ch=getchar();
    	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    	return x*f;
    }
    
    struct segment_tree {
    	int tree[maxn<<2],add_tag[maxn<<2],mul_tag[maxn<<2];
    
    	void updata(int p) {
    		tree[p]=(tree[p<<1]+tree[p<<1|1])%pps;
    	}
    
    	void build(int p,int l,int r) {
    		if(l==r) {
    			tree[p]=a[l];
    			return;
    		}mul_tag[p]=1,add_tag[p]=0;//乘1加0等于本身
    		int mid=(l+r)>>1;
    		build(p<<1,l,mid);
    		build(p<<1|1,mid+1,r);
    		updata(p);
    	}
    
    	void add_add_tag(int p,int l,int r,int v) {
    		tree[p]=(tree[p]+1ll*(r-l+1)*v%pps)%pps;
    		add_tag[p]=(add_tag[p]+v)%pps;
    	}
    
    	void add_mul_tag(int p,int l,int r,int v) {
    		tree[p]=1ll*tree[p]*v%pps;
    		add_tag[p]=1ll*add_tag[p]*v%pps;
    		mul_tag[p]=1ll*mul_tag[p]*v%pps;
    	}
    
    	void push_down(int p,int l,int r) {
    		int mid=(l+r)>>1;
    		if(mul_tag[p]!=1) {
    			add_mul_tag(p<<1,l,mid,mul_tag[p]);
    			add_mul_tag(p<<1|1,mid+1,r,mul_tag[p]);
    			mul_tag[p]=1;
    		}
    		if(add_tag[p]) {
    			add_add_tag(p<<1,l,mid,add_tag[p]);
    			add_add_tag(p<<1|1,mid+1,r,add_tag[p]);
    			add_tag[p]=0;
    		}
    	}
    
    	void change_mul(int p,int l,int r,int L,int R,int v) {
    		if(L<=l&&r<=R) {
    			add_mul_tag(p,l,r,v);
    			return;
    		}
    		int mid=(l+r)>>1;push_down(p,l,r);
    		if(L<=mid)change_mul(p<<1,l,mid,L,R,v);
    		if(R>mid)change_mul(p<<1|1,mid+1,r,L,R,v);
    		updata(p);
    	}
    
    	void change_add(int p,int l,int r,int L,int R,int v) {
    		if(L<=l&&r<=R) {
    			add_add_tag(p,l,r,v);
    			return;
    		}
    		int mid=(l+r)>>1;push_down(p,l,r);
    		if(L<=mid)change_add(p<<1,l,mid,L,R,v);
    		if(R>mid)change_add(p<<1|1,mid+1,r,L,R,v);
    		updata(p);
    	}
    
    	int query(int p,int l,int r,int L,int R) {
    		if(L<=l&&r<=R)return tree[p];
    		int mid=(l+r)>>1,res=0;push_down(p,l,r);
    		if(L<=mid)res=query(p<<1,l,mid,L,R);
    		if(R>mid)res=(res+query(p<<1|1,mid+1,r,L,R))%pps;
    		return res;
    	}
    }T;
    
    int main() {
    	n=read(),pps=read();
    	for(int i=1;i<=n;i++)
    		a[i]=read()%pps;
    	T.build(1,1,n);m=read();
    	for(int i=1;i<=m;i++) {
    		int opt=read(),l=read(),r=read(),v;
    		if(opt!=3)v=read();
    		if(opt==1)T.change_mul(1,1,n,l,r,v);
    		else if(opt==2)T.change_add(1,1,n,l,r,v);
    		else printf("%d
    ",T.query(1,1,n,l,r));
    	}
    	return 0;
    }
    
  • 相关阅读:
    0313学习进度条
    0311 了解和熟悉操作系统实验
    学习进度条博客
    0302 关于就业的感想
    1230递归下降语法分析程序设计
    有限自动机的构造和识别
    评论
    C语言文法
    编译原理第二次作业——词法分析心得
    0428团队项目2.0
  • 原文地址:https://www.cnblogs.com/AKMer/p/9947690.html
Copyright © 2011-2022 走看看