• 【BZOJ 1798】[Ahoi2009]Seq 维护序列seq


    乘法和加法可以都保留 加个小处理!

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define MAXN 100000
    #define LL long long
    LL a[MAXN*4],c[MAXN*4],j[MAXN*4],num[MAXN*4];
    LL n,p,m;
    void Build(int now,int L,int R)
    {
    	c[now]=1;
    	if(L==R) {a[now]=num[L];return;}
    	int mid=(L+R)/2;
    	Build(now*2,L,mid);
    	Build(now*2+1,mid+1,R);
    	a[now]=a[now*2]+a[now*2+1];
    }
    void Pushdown(int now,int L,int R)
    {
    	int mid=(L+R)/2;
    	if(L!=R) 
    	{
    		c[now*2]*=c[now];						a[now*2]*=c[now];
    		c[now*2+1]*=c[now];						a[now*2+1]*=c[now];
    		j[now*2]=j[now*2]*c[now]+j[now];		a[now*2]+=(mid-L+1)*j[now];
    		j[now*2+1]=j[now*2+1]*c[now]+j[now];	a[now*2+1]+=(R-mid)*j[now];
    		c[now*2]%=p;
    		c[now*2+1]%=p;
    		j[now*2]%=p;
    		j[now*2+1]%=p;
    		a[now*2]%=p;
    		a[now*2+1]%=p;
    	}
    	c[now]=1;j[now]=0;
    }
    void Change(int now,int L,int R,int s,int t,int cc,int jj)
    {
    	
    	if(s<=L&&R<=t) {c[now]*=cc;c[now]%=p;j[now]=(j[now]*cc+jj)%p;a[now]*=cc;a[now]+=(R-L+1)*jj;a[now]%=p;return;}
    	Pushdown(now,L,R);
    	int mid=(L+R)/2;
    	if(t<=mid) Change(now*2,L,mid,s,t,cc,jj);
    	else if(s>=mid+1) Change(now*2+1,mid+1,R,s,t,cc,jj);
    	else Change(now*2,L,mid,s,t,cc,jj),Change(now*2+1,mid+1,R,s,t,cc,jj);
    	a[now]=(a[now*2]+a[now*2+1])%p;
    }
    int Query(int now,int L,int R,int s,int t)
    {
    	if(s<=L&&R<=t) return a[now];
    	Pushdown(now,L,R);
    	int mid=(L+R)/2;
    	if(t<=mid) return Query(now*2,L,mid,s,t)%p;
    	else if(s>=mid+1) return Query(now*2+1,mid+1,R,s,t)%p;
    	else return (Query(now*2,L,mid,s,t)+Query(now*2+1,mid+1,R,s,t))%p;
    }
    inline int Read()
    {
    	int ans=0;
    	char c=getchar();
    	while(c<'0'||c>'9') c=getchar();
    	while('0'<=c&&c<='9')ans=ans*10+c-'0',c=getchar();
    	return ans;
    }
    int main()
    {
    	scanf("%lld %lld",&n,&p);
    	for(int i=1;i<=n;i++) num[i]=Read();
    	Build(1,1,n);
    	scanf("%lld",&m);
    	for(int opt,x,y,z,i=1;i<=m;i++)
    	{
    		opt=Read();
    		switch(opt)
    		{
    			case 1:x=Read(),y=Read(),z=Read();Change(1,1,n,x,y,z,0);break;
    			case 2:x=Read(),y=Read(),z=Read();Change(1,1,n,x,y,1,z);break;
    			case 3:x=Read();y=Read();printf("%d\n",Query(1,1,n,x,y));break;
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    java基础-BigDecimal类常用方法介绍
    java基础-BigInteger类常用方法介绍
    java基础-Arrays类常用方法介绍
    java基础-Math类常用方法介绍
    java基础-System类常用方法介绍
    java基础-Integer类常用方法介绍
    java基础-数组的折半查找原理
    Java基础-数组常见排序方式
    Java基础-日期格式化DateFormat类简介
    Java基础-Calendar类常用方法介绍
  • 原文地址:https://www.cnblogs.com/ofsxb/p/5115517.html
Copyright © 2020-2023  润新知