zoukankan      html  css  js  c++  java
  • BZOJ 1798 AHOI2009 Seq 维护序列 线段树

    题目大意:维护一个序列,提供三种操作:

    1.将区间中每个点的权值乘上一个数

    2.将区间中每个点的权值加上一个数

    3.求一段区间的和对p取模的值

    2631的超^n级弱化版。写2631之前能够拿这个练练手。。。

    线段树区间改动,让学校的大神指导了一下ZKW的区间改动方法,非常好理解,可是代码还是快不了。

    回头再改改代码吧 可能是我写的太渣了

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define M 100100
    using namespace std;
    typedef long long ll;
    struct abcd{
        ll sum,siz,add_mark,times_mark;
        void add(ll x);
        void times(ll x);
    }tree[263000];
    int m,n,p,q;
    void abcd :: add(ll x)
    {
        sum+=x*siz;
        sum%=p;
        add_mark+=x;
        add_mark%=p;
    }
    void abcd :: times(ll x)
    {
        sum*=x;
        sum%=p;
        add_mark*=x;
        add_mark%=p;
        times_mark*=x;
        times_mark%=p;
    }
    void Build_Tree()
    {
        int i;
        for(i=q+1;i<=q+n;i++)
        {
            scanf("%d",&tree[i].sum);
            tree[i].siz=1;
            tree[i].add_mark=0;
            tree[i].times_mark=1;
        }
        for(i=q-1;i;i--)
        {
            tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;
            tree[i].sum%=p;
            tree[i].siz=tree[i<<1].siz+tree[i<<1|1].siz;
            tree[i].add_mark=0;
            tree[i].times_mark=1;
        }
    }
    int stack[M],top;
    void Push_Down(int x)
    {
        if(x>=q)
            return ;
        if(tree[x].times_mark^1)
        {
            tree[x<<1  ].times(tree[x].times_mark);
            tree[x<<1|1].times(tree[x].times_mark);
            tree[x].times_mark=1;
        }
        if(tree[x].add_mark)
        {
            tree[x<<1  ].add(tree[x].add_mark);
            tree[x<<1|1].add(tree[x].add_mark);
            tree[x].add_mark=0;
        }
    }
    void Push_Down(int x,int y)
    {
        for(x+=q-1,y+=q+1;x^y;x>>=1,y>>=1)
            stack[++top]=x,stack[++top]=y;
        for(;x;x>>=1)
            stack[++top]=x;
        while(top)
            Push_Down(stack[top--]);
    }
    void Add(int x,int y,ll z)
    {
        for(x+=q-1,y+=q+1;x^y^1;x>>=1,y>>=1)
        {
            if(~x&1)tree[x^1].add(z);
            if( y&1)tree[y^1].add(z);
        }
    }
    void Times(int x,int y,ll z)
    {
        for(x+=q-1,y+=q+1;x^y^1;x>>=1,y>>=1)
        {
            if(~x&1)tree[x^1].times(z);
            if( y&1)tree[y^1].times(z);
        }
    }
    void Push_Up(int x)
    {
        if(x>=q)
            return ;
        tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum;
        tree[x].sum%=p;
    }
    void Push_Up(int x,int y)
    {
        for(x+=q-1,y+=q+1;x^y;x>>=1,y>>=1)
            Push_Up(x),Push_Up(y);
        for(;x;x>>=1)
            Push_Up(x);
    }
    ll Get_Ans(int x,int y)
    {
        int re=0;
        for(x+=q-1,y+=q+1;x^y^1;x>>=1,y>>=1)
        {
            if(~x&1)re+=tree[x^1].sum,re%=p;
            if( y&1)re+=tree[y^1].sum,re%=p;
        }
        return re;
    }
    int main()
    {
        int i,x,y,c;
        ll z;
        cin>>n>>p;
        for(q=1;q<=n+1;q<<=1);
        Build_Tree();
        cin>>m;
        for(i=1;i<=m;i++)
        {
            scanf("%d",&c);
            if(c==1)
            {
                scanf("%d%d%lld",&x,&y,&z);
                Push_Down(x,y);
                Times(x,y,z);
                Push_Up(x,y);
            }
            else if(c==2)
            {
                scanf("%d%d%lld",&x,&y,&z);
                Push_Down(x,y);
                Add(x,y,z);
                Push_Up(x,y);
            }
            else
            {
                scanf("%d%d",&x,&y);
                Push_Down(x,y);
                printf("%lld
    ", Get_Ans(x,y) );
            }
        }
    }
    


  • 相关阅读:
    有多少程序员超过四十岁呢?
    乔布斯的演讲技巧:教你站在讲台上怎样化腐朽为神奇
    想要好看的WORDPRESS模板
    多些时间能少写些代码
    java播放au音频程序
    明星软件工程师的10种特质
    中国互联网创业的四个机遇
    Android环境搭建
    想写代码?离开你的电脑吧!
    深讨Java SE 6 在 HTTP 方面的新特性(NTLM)
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6766807.html
Copyright © 2011-2022 走看看