zoukankan      html  css  js  c++  java
  • COGS.1272.[AHOI2009]行星序列(线段树 区间加、乘、求和)

    题目链接

    //注意取模! 
    #include<cstdio>
    #include<cctype>
    using namespace std;
    const int N=1e5+5;
    
    int n,mod,Sum[N<<2],aTag[N<<2],mTag[N<<2];
    
    inline int read()
    {
    	int now=0,f=1;register char c=getchar();
    	for(;!isdigit(c);c=getchar())
    	  if(c=='-') f=-1;
    	for(;isdigit(c);now=now*10+c-'0',c=getchar());
    	return now*f;
    }
    
    inline void PushUp(int rt)
    {
    	Sum[rt]=(Sum[rt<<1]+Sum[rt<<1|1])%mod;
    }
    inline void PushDown(int m,int rt)
    {
    	if(mTag[rt]!=1)
    	{
    		mTag[rt<<1]=1ll*mTag[rt<<1]*mTag[rt]%mod;
    		mTag[rt<<1|1]=1ll*mTag[rt<<1|1]*mTag[rt]%mod;
    		aTag[rt<<1]=1ll*aTag[rt<<1]*mTag[rt]%mod;
    		aTag[rt<<1|1]=1ll*aTag[rt<<1|1]*mTag[rt]%mod;
    		Sum[rt<<1]=1ll*Sum[rt<<1]*mTag[rt]%mod;
    		Sum[rt<<1|1]=1ll*Sum[rt<<1|1]*mTag[rt]%mod;
    		mTag[rt]=1;
    	}
    	if(aTag[rt])
    	{
    		aTag[rt<<1]+=aTag[rt], aTag[rt<<1]%=mod;
    		aTag[rt<<1|1]+=aTag[rt], aTag[rt<<1|1]%=mod;
    		Sum[rt<<1]=(1ll*Sum[rt<<1]+1ll*(m-(m>>1))*aTag[rt]%mod)%mod;
    		Sum[rt<<1|1]=(1ll*Sum[rt<<1|1]+1ll*(m>>1)*aTag[rt]%mod)%mod;
    		aTag[rt]=0;
    	}
    }
    void Build(int l,int r,int rt)
    {
    	mTag[rt]=1;
    	if(l==r)
    	{
    		Sum[rt]=read()%mod;
    		return;
    	}
    	int m=l+r>>1;
    	Build(l,m,rt<<1),Build(m+1,r,rt<<1|1);
    	PushUp(rt);
    }
    void Modify_Add(int l,int r,int rt,int L,int R,int v)
    {
    	if(L<=l && r<=R)
    	{
    		aTag[rt]+=v;
    		if(aTag[rt]>=mod) aTag[rt]-=mod;
    		Sum[rt]=(1ll*Sum[rt]+1ll*v*(r-l+1))%mod;
    		return;
    	}
    	PushDown(r-l+1,rt);
    	int m=l+r>>1;
    	if(L<=m) Modify_Add(l,m,rt<<1,L,R,v);
    	if(m<R) Modify_Add(m+1,r,rt<<1|1,L,R,v);
    	PushUp(rt);
    }
    void Modify_Mult(int l,int r,int rt,int L,int R,int v)
    {
    	if(L<=l && r<=R)
    	{
    		aTag[rt]=1ll*aTag[rt]*v%mod;
    		mTag[rt]=1ll*mTag[rt]*v%mod;
    		Sum[rt]=1ll*Sum[rt]*v%mod;
    		return;
    	}
    	PushDown(r-l+1,rt);
    	int m=l+r>>1;
    	if(L<=m) Modify_Mult(l,m,rt<<1,L,R,v);
    	if(m<R) Modify_Mult(m+1,r,rt<<1|1,L,R,v);
    	PushUp(rt);
    }
    int Query_Sum(int l,int r,int rt,int L,int R)
    {
    	if(L<=l && r<=R) return Sum[rt];
    	PushDown(r-l+1,rt);
    	int m=l+r>>1;long long res=0;
    	if(L<=m) res+=Query_Sum(l,m,rt<<1,L,R), res%=mod;
    	if(m<R) res+=Query_Sum(m+1,r,rt<<1|1,L,R), res%=mod;
    	return res;
    }
    
    int main()
    {
    	freopen("seqb.in","r",stdin);
    	freopen("seqb.out","w",stdout);
    
    	n=read(),mod=read();
    	Build(1,n,1);
    	int m=read(),opt,l,r,v;
    	while(m--)
    	{
    		opt=read(),l=read(),r=read();
    		if(opt==1)
    			v=read(), Modify_Mult(1,n,1,l,r,v);
    		else if(opt==2)
    			v=read(), Modify_Add(1,n,1,l,r,v);
    		else
    			printf("%d
    ",Query_Sum(1,n,1,l,r));
    	}
    
    	fclose(stdin);fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    vue-面试
    使用webpack4搭建一个基于Vue的组件库
    vue 仿今日头条
    如何正确的在项目中接入微信JS-SDK
    vuejs实现折叠面板展开收缩动画
    Vue的watch和computed属性
    Android Studio(十):添加assets目录
    Android Studio(九):引用jar及so文件
    Android Studio(八):Android Studio设置教程
    Android Studio(七):项目从Eclipse到Android Studio迁移
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8444260.html
Copyright © 2011-2022 走看看