• 线段树


    //线段树区间/单点加、减、乘、赋值,查询区间/单点和、最大值、最小值。
    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    namespace IO
    {
        const int InputBufferSize = 48*1024*1024;
        const int OutputBufferSize = 48*1024*1024;
        namespace input
        {
            char buffer[InputBufferSize],*s,*eof;
            inline void init()
            {
                s=buffer;
                eof=s+fread(buffer,1,InputBufferSize,stdin);
            }
            inline bool read(long long &x)
            {
                x=0;
                int flag=1;
                while(!isdigit(*s)&&*s!='-')
                    s++;
                if(eof<=s)
                    return false;
                if(*s=='-')
                {
                    flag=-1;
                    s++;
                }
                while(isdigit(*s))
                    x=x*10+*s++-'0';
                x*=flag;
                return true;
            }
            inline bool read(int &x)
            {
                x=0;
                int flag=1;
                while(!isdigit(*s)&&*s!='-')
                    s++;
                if(eof<=s)
                    return false;
                if(*s=='-')
                {
                    flag=-1,s++;
                }
                while(isdigit(*s))
                    x=x*10+*s++-'0';
                x*=flag;
                return true;
            }
            inline bool read(char *str)
            {
                *str=0;
                while(isspace(*s))
                    s++;
                if(eof<s)
                    return false;
                while(!isspace(*s))
                {
                    *str=0;
                    *str=*s;
                    str++;
                    s++;
                }
                *str=0;
                return true;
            }
            inline bool read(char &ch)
            {
                ch=0;
                while(isspace(*s))
                    s++;
                if(eof<s)
                    return false;
                ch=0;
                ch=*s;
                s++;
                return true;
            }
        }
        namespace output
        {
            char buffer[OutputBufferSize];
            char *s=buffer;
            inline void flush()
            {
                fwrite(buffer,1,s-buffer,stdout);
                s=buffer;
            }
            inline void print(const char ch)
            {
                if(s-buffer>OutputBufferSize-2)
                    flush();
                *s++=ch;
            }
            inline void print(char *str)
            {
                while(*str!=0)
                    print(char(*str++));
            }
            inline void print(long long x)
            {
                char buf[25]= {0},*p=buf;
                if(x<0)
                {
                    print('-');
                    x=-x;
                }
                if(x==0)
                    print('0');
                while(x)
                {
                    *(++p)=x%10;
                    x/=10;
                }
                while(p!=buf)
                    print(char(*(p--)+'0'));
            }
            inline void print(int x)
            {
                char buf[25]= {0},*p=buf;
                if(x<0)
                {
                    print('-');
                    x=-x;
                }
                if(x==0)
                    print('0');
                while(x)
                {
                    *(++p)=x%10;
                    x/=10;
                }
                while(p!=buf)
                    print(char(*(p--)+'0'));
            }
        }
        using namespace input;
        using namespace output;
    }
    using namespace IO;
    namespace SegmentTree
    {
    #define mid ((l+r)>>1)
    #define lson (o<<1)
    #define rson (lson|1)
        long long p;
        long long sum[800010];
        long long addv[800010];
        long long mulv[800010];
        long long Min[800010];
        long long Max[800010];
        long long chav[800010];
        bool c[800010];
        inline void push_up(int o)
        {
            sum[o]=(sum[lson]+sum[rson])%p;
            Min[o]=(min(Min[lson],Min[rson]))%p;
            Max[o]=(max(Max[lson],Max[rson]))%p;
        }
        void build(int o,int l,int r)
        {
            addv[o]=0;
            mulv[o]=1;
            chav[o]=0;
            c[o]=false;
            if(l==r)
            {
                read(sum[o]);
                Min[o]=sum[l];
                Max[o]=sum[l];
                return;
            }
            build(lson,l,mid);
            build(rson,mid+1,r);
            push_up(o);
        }
        inline void push_down(int o,int l,int r,int mi,int ls,int rs)
        {
            if(c[o])
            {
                mulv[ls]=1;
                mulv[rs]=1;
                addv[ls]=0;
                addv[rs]=0;
                sum[ls]=((mi-l+1)*chav[ls])%p;
                sum[rs]=((r-mi)*chav[rs])%p;
                Min[ls]=chav[o];
                Min[rs]=chav[o];
                Max[ls]=chav[o];
                Max[rs]=chav[o];
                chav[o]=0;
                c[o]=false;
            }
            if(mulv[o]!=1)
            {
                mulv[ls]=(mulv[ls]*mulv[o])%p;
                mulv[rs]=(mulv[rs]*mulv[o])%p;
                addv[ls]=(addv[ls]*mulv[o])%p;
                addv[rs]=(addv[rs]*mulv[o])%p;
                sum[ls]=(sum[ls]*mulv[o])%p;
                sum[rs]=(sum[rs]*mulv[o])%p;
                Min[ls]=(Min[ls]*mulv[o])%p;
                Min[rs]=(Min[rs]*mulv[o])%p;
                Max[ls]=(Max[ls]*mulv[o])%p;
                Max[rs]=(Max[rs]*mulv[o])%p;
                mulv[o]=1;
            }
            if(addv[o]!=0)
            {
                addv[ls]=(addv[ls]+addv[o])%p;
                addv[rs]=(addv[rs]+addv[o])%p;
                sum[ls]=(sum[ls]+(mi-l+1)*addv[o])%p;
                sum[rs]=(sum[rs]+(r-mi)*addv[o])%p;
                Min[ls]=(Min[ls]+addv[o])%p;
                Min[rs]=(Min[rs]+addv[o])%p;
                Max[ls]=(Max[ls]+addv[o])%p;
                Max[rs]=(Max[rs]+addv[o])%p;
                addv[o]=0;
            }
        }
        void addall(int o,int l,int r,int a,int b,int x)
        {
            if(l>=a&&r<=b)
            {
                addv[o]=(addv[o]+x)%p;
                sum[o]=(sum[o]+(r-l+1)*x)%p;
                return;
            }
            push_down(o,l,r,mid,lson,rson);
            if(a<=mid)
                addall(lson,l,mid,a,b,x);
            if(b>mid)
                addall(rson,mid+1,r,a,b,x);
            push_up(o);
        }
        void mulall(int o,int l,int r,int a,int b,int x)
        {
            if(l>=a&&r<=b)
            {
                mulv[o]=(mulv[o]*x)%p;
                addv[o]=(addv[o]*x)%p;
                sum[o]=(sum[o]*x)%p;
                return;
            }
            push_down(o,l,r,mid,lson,rson);
            if(a<=mid)
                mulall(lson,l,mid,a,b,x);
            if(b>mid)
                mulall(rson,mid+1,r,a,b,x);
            push_up(o);
        }
        void chaall(int o,int l,int r,int a,int b,int x)
        {
            if(l>=a&&r<=b)
            {
                chav[o]=x%p;
                sum[o]=x*(r-l+1)%p;
                Max[o]=x%p;
                Min[o]=x%p;
                addv[o]=0;
                mulv[o]=1;
                c[o]=true;
                return;
            }
            push_down(o,l,r,mid,lson,rson);
            if(a<=mid)
                chaall(lson,l,mid,a,b,x);
            if(b>mid)
                chaall(rson,mid+1,r,a,b,x);
            push_up(o);
        }
        long long querySum(int o,int l,int r,int a,int b)
        {
            if(l>=a&&r<=b)
                return sum[o]%p;
            long long ans=0;
            push_down(o,l,r,mid,lson,rson);
            if(a<=mid)
                ans+=querySum(lson,l,mid,a,b);
            if(b>mid)
                ans+=querySum(rson,mid+1,r,a,b);
            return ans%p;
        }
        long long queryMax(int o,int l,int r,int a,int b)
        {
            if(l>=a&&r<=b)
                return Max[o]%p;
            long long ans=0;
            push_down(o,l,r,mid,lson,rson);
            if(a<=mid)
                ans=max(ans,queryMax(lson,l,mid,a,b));
            if(b>mid)
                ans=max(ans,queryMax(rson,mid+1,r,a,b));
            return ans%p;
        }
        long long queryMin(int o,int l,int r,int a,int b)
        {
            if(l>=a&&r<=b)
                return Min[o]%p;
            long long ans=0x7fffffffffffffff;
            push_down(o,l,r,mid,lson,rson);
            if(a<=mid)
                ans=min(ans,queryMin(lson,l,mid,a,b));
            if(b>mid)
                ans=min(ans,queryMin(rson,mid+1,r,a,b));
            return ans%p;
        }
    #undef mid
    #undef lson
    #undef rson
    }
    using namespace SegmentTree;
    int n,m,i,f;
    int x,y;
    long long k;
    int main()
    {
    #ifdef LOCAL
        freopen("data.in","rb",stdin);
    #endif
        init();
        read(n),read(m),read(p);
        build(1,1,n);
        while(m--)
        {
            read(f);
            switch(f)
            {
                case 1:
                    read(x);
                    read(y);
                    read(k);
                    mulall(1,1,n,x,y,k);
                    break;
                case 2:
                    read(x);
                    read(y);
                    read(k);
                    addall(1,1,n,x,y,k);
                    break;
                case 3:
                    read(x);
                    read(y);
                    print(querySum(1,1,n,x,y)),print('
    ');
                    break;
                case 4:
                    read(x);
                    read(y);
                    read(k);
                    chaall(1,1,n,x,y,k);
                    break;
            }
        }
        flush();
        return 0;
    }
    

      

  • 相关阅读:
    在 .NET 3.5 中序列化和反序列化 JSON Kevin
    .NET 3.5 获取不全Cookie的问题 Kevin
    C#反序列化JSON数组对象 Kevin
    使用ConfigurationManager类 读写配置文件 Kevin
    C# post数据时 出现如下错误: System.Net.WebException: 远程服务器返回错误: (417) Expectation Failed 的解决办法 Kevin
    .NET 关于反序列化 JSON 对象数组的问题 Kevin
    为什么调用thread.Abort(),线程不会马上停止 Kevin
    vs2005调用迅雷完美解决方案 Kevin
    .NET 复杂的 DataBinding 接受 IList 或 IListSource 作为数据源 Kevin
    找不到DataContract属性! Kevin
  • 原文地址:https://www.cnblogs.com/TheRoadToAu/p/8693503.html
Copyright © 2020-2023  润新知