zoukankan      html  css  js  c++  java
  • [bzoj1798][Ahoi2009]Seq 维护序列seq

    题意:给定一个序列,要支持区间加,区间乘,区间求和   $n,mleqslant 100000$

    题解:线段树练练手

    #include<iostream>
    #include<cstdio>
    #define MN 100000
    #define ll long long
    using namespace std;
    inline int read()
    {
        int x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    
    int n,m,s[MN+5],mod;
    struct TREE{
        int l,r;ll x,ad,val;
    }T[MN*8+5];
    
    void pushdown(int x)
    {
        int l=x<<1,r=x<<1|1;
        if(T[x].val!=1)
        {
            T[l].ad*=T[x].val;T[r].ad*=T[x].val;
            T[l].val*=T[x].val;T[r].val*=T[x].val;
            T[l].ad%=mod;T[r].ad%=mod; 
            T[l].val%=mod;T[r].val%=mod;
        }
        if(T[x].ad)
        {
            T[l].ad=(T[l].ad+T[x].ad)%mod;
            T[r].ad=(T[r].ad+T[x].ad)%mod;
        }
        T[l].x=(T[l].x*T[x].val%mod+1LL*(T[l].r-T[l].l+1)*T[x].ad)%mod;
        T[r].x=(T[r].x*T[x].val%mod+1LL*(T[r].r-T[r].l+1)*T[x].ad)%mod;
        T[x].val=1;T[x].ad=0;
    }
    
    void build(int x,int l,int r)
    {
        T[x].val=1;
        if((T[x].l=l)==(T[x].r=r)) {T[x].x=s[l];return;}
        int mid=l+r>>1;
        build(x<<1,l,mid);build(x<<1|1,mid+1,r);
        T[x].x=(T[x<<1].x+T[x<<1|1].x)%mod;
    }
    
    void modify(int x,int l,int r,ll ad)
    {
         pushdown(x);
        if(T[x].l==l&&T[x].r==r)
        {
            T[x].ad+=ad;T[x].x+=1LL*(r-l+1)*ad;
            T[x].x%=mod;T[x].ad%=mod;
            return;
        }
        int mid=T[x].l+T[x].r>>1;
        if(r<=mid)modify(x<<1,l,r,ad);
        else if(l>mid) modify(x<<1|1,l,r,ad);
        else {modify(x<<1,l,mid,ad);modify(x<<1|1,mid+1,r,ad);}
        T[x].x=(T[x<<1].x+T[x<<1|1].x)%mod;
    }
    
    void renew(int x,int l,int r,ll val)
    {
        pushdown(x);
        if(T[x].l==l&&T[x].r==r)
        {
            T[x].val*=val;T[x].val%=mod;
            T[x].x*=val;T[x].x%=mod;
            return;
        }
        int mid=T[x].l+T[x].r>>1;
        if(r<=mid)renew(x<<1,l,r,val);
        else if(l>mid) renew(x<<1|1,l,r,val);
        else {renew(x<<1,l,mid,val);renew(x<<1|1,mid+1,r,val);}
        T[x].x=(T[x<<1].x+T[x<<1|1].x)%mod;
    }
    
    ll query(int x,int l,int r)
    {
         pushdown(x);
        if(T[x].l==l&&T[x].r==r)return T[x].x;
        int mid=T[x].l+T[x].r>>1;
        if(r<=mid) return query(x<<1,l,r);
        else if(l>mid) return query(x<<1|1,l,r);
        else return (query(x<<1,l,mid)+query(x<<1|1,mid+1,r))%mod;
    }
    
    int main()
    {
        n=read();mod=read();
        for(int i=1;i<=n;i++)s[i]=read();
        build(1,1,n);
        m=read();
        for(int i=1;i<=m;i++)
        {
            int op=read(),l=read(),r=read();
            if(op==3) printf("%d
    ",(int)query(1,l,r));
            else 
            {
                int x=read();
                if(op==2) modify(1,l,r,x);
                else renew(1,l,r,x); 
            } 
        }
        return 0;
    }
  • 相关阅读:
    Liferay 6.2 改造系列之十五:修改默认可用语言
    Liferay 6.2 改造系列之十七:当Portlet无权限时,不显示错误信息
    Liferay 6.2 改造系列之十四:修改组织的表单内容
    Liferay 6.2 改造系列之十三:修改用户编辑页面表单内容
    Liferay 6.2 改造系列之十一:默认关闭CDN动态资源
    matlab向量的排序(自写函数)
    matlab求一个矩阵中各元素出现的个数(归一化)
    matlab求矩阵的鞍点
    matlab求矩阵、向量的模
    matlab求最大公约数和最小公倍数
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj1798.html
Copyright © 2011-2022 走看看