zoukankan      html  css  js  c++  java
  • P2023 [AHOI2009]维护序列 (线段树区间修改查询)

    题目链接:https://www.luogu.org/problemnew/show/P2023

    一道裸的线段树区间修改题,懒惰数组注意要先乘后加

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int maxx = 400010;
    LL tree[maxx],lazy1[maxx],lazy2[maxx],a[maxx],mod;
    int n;
    void build(int l,int r,int temp)
    {
        lazy1[temp]=1;lazy2[temp]=0;
        if(l==r)
        {
            tree[temp]=a[l]%mod;
            return;
        }
        int mid=(l+r)/2;
        build(l,mid,temp*2);
        build(mid+1,r,temp*2+1);
        tree[temp]=(tree[temp*2]+tree[temp*2+1])%mod;
    }
    void pushdown(int l,int r,int temp)
    {
        //lazy1[temp*2]=a0,lazy2[temp*2]=b0,lazy1[temp]=a
        //a0*x+b0->a*(a0*x+b0)->a*a0*x+a*b0
        tree[temp*2]=(tree[temp*2]*lazy1[temp]+l*lazy2[temp])%mod;
        tree[temp*2+1]=(tree[temp*2+1]*lazy1[temp]+r*lazy2[temp])%mod;
        lazy1[temp*2]=(lazy1[temp*2]*lazy1[temp])%mod;
        lazy1[temp*2+1]=(lazy1[temp*2+1]*lazy1[temp])%mod;
        lazy2[temp*2]=(lazy2[temp*2]*lazy1[temp]+lazy2[temp])%mod;
        lazy2[temp*2+1]=(lazy2[temp*2+1]*lazy1[temp]+lazy2[temp])%mod;
        lazy1[temp]=1;lazy2[temp]=0;
    }
    void add1(int l,int r,int p,int q,LL c,int temp)
    {
        if(p<=l&&r<=q)
        {
            tree[temp]=(tree[temp]*c)%mod;
            lazy1[temp]=(lazy1[temp]*c)%mod;
            lazy2[temp]=(lazy2[temp]*c)%mod;//注意这里,乘的发生改变加的就要改变
            return;
        }
        int mid=(l+r)/2;
        pushdown(mid-l+1,r-mid,temp);
        if(mid>=p)add1(l,mid,p,q,c,temp*2);
        if(mid<q)add1(mid+1,r,p,q,c,temp*2+1);
        tree[temp]=(tree[temp*2]+tree[temp*2+1])%mod;
    }
    void add2(int l,int r,int p,int q,LL c,int temp)
    {
        if(p<=l&&r<=q)
        {
            tree[temp]=(tree[temp]+(r-l+1)*c)%mod;
            lazy2[temp]=(lazy2[temp]+c)%mod;
            return;
        }
        int mid=(l+r)/2;
        pushdown(mid-l+1,r-mid,temp);
        if(mid>=p)add2(l,mid,p,q,c,temp*2);
        if(mid<q)add2(mid+1,r,p,q,c,temp*2+1);
        tree[temp]=(tree[temp*2]+tree[temp*2+1])%mod;
    }
    LL get(int l,int r,int p,int q,int temp)
    {
        if(p<=l&&r<=q)return tree[temp];
        int mid=(l+r)/2;
        LL res=0;
        pushdown(mid-l+1,r-mid,temp);
        if(mid>=p)res=(res+get(l,mid,p,q,temp*2))%mod;
        if(mid<q)res=(res+get(mid+1,r,p,q,temp*2+1))%mod;
        return res;
    }
    int main()
    {
        scanf("%d %lld",&n,&mod);
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        build(1,n,1);
        int m,s,t,g;
        LL c;
        scanf("%d",&m);
        while(m--)
        {
            scanf("%d",&s);
            if(s==1)
            {
                scanf("%d%d%lld",&t,&g,&c);
                add1(1,n,t,g,c,1);
            }
            else if(s==2)
            {
                scanf("%d%d%lld",&t,&g,&c);
                add2(1,n,t,g,c,1);
            }
            else
            {
                scanf("%d%d",&t,&g);
                LL ans=get(1,n,t,g,1);
                printf("%lld
    ",ans);
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    [UOJ#391]GEGEGE
    [GOODBYE WUXU][UOJ]
    codeforce 1110F
    [atcoder][abc123D]
    [atcoder][agc001]
    Luogu1070-道路游戏-动态规划
    Luogu 2577[ZJOI2005]午餐
    Luogu 1169 [ZJOI2007]棋盘制作
    Luogu 1273 有线电视网
    Luogu 2279 [HNOI2003]消防局的设立
  • 原文地址:https://www.cnblogs.com/HooYing/p/11247399.html
Copyright © 2011-2022 走看看