zoukankan      html  css  js  c++  java
  • AC日记——【模板】线段树 2 洛谷 P3373

    P3373 【模板】线段树 2
    387
    通过
    1.8K
    提交
    标签
    难度 提高+/省选-
    提交 讨论 题解

    最新讨论 更多讨论

    2333
    最后三个点卡常数。
    迷之RE
    感觉这题很迷啊
    好像一共三组测试数据。
    友情提示:开long long
    题目描述

    如题,已知一个数列,你需要进行下面两种操作:

    1.将某区间每一个数加上x

    2.将某区间每一个数乘上x

    3.求出某区间每一个数的和

    输入输出格式

    输入格式:
    第一行包含三个整数N、M、P,分别表示该数列数字的个数、操作的总个数和模数。

    第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

    接下来M行每行包含3或4个整数,表示一个操作,具体如下:

    操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k

    操作2: 格式:2 x y k 含义:将区间[x,y]内每个数加上k

    操作3: 格式:3 x y 含义:输出区间[x,y]内每个数的和对P取模所得的结果

    输出格式:
    输出包含若干行整数,即为所有操作3的结果。

    输入输出样例

    输入样例#1:
    5 5 38
    1 5 4 2 3
    2 1 4 1
    3 2 5
    1 2 4 2
    2 3 5 5
    3 1 4
    输出样例#1:
    17
    2
    说明

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=8,M<=10

    对于70%的数据:N<=1000,M<=10000

    对于100%的数据:N<=100000,M<=100000

    (数据已经过加强^_^)

    样例说明:

    故输出应为17、2(40 mod 38=2)

    思路:

      裸线段树;

    来,上代码:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    #define maxn 100005
    #define LL long long
    
    using namespace std;
    
    struct TreeNodeType {
        LL l,r,dis,mid,flag,flag_;
        
        bool if_;
    };
    struct TreeNodeType tree[maxn<<2],*lc,*rc;
    
    LL if_z,n,m,type,x,p,ans;
    
    char Cget;
    
    inline void in(LL &now)
    {
        now=0,if_z=1,Cget=getchar();
        while(Cget>'9'||Cget<'0')
        {
            if(Cget=='-') if_z=-1;
            Cget=getchar();
        }
        while(Cget>='0'&&Cget<='9')
        {
            now=now*10+Cget-'0';
            Cget=getchar();
        }
        now*=if_z;
    }
    
    void tree_build(LL now,LL l,LL r)
    {
        tree[now].l=l,tree[now].r=r;
        if(l==r)
        {
            in(tree[now].dis);
            return ;
        }
        tree[now].mid=(l+r)>>1;
        tree_build(now<<1,l,tree[now].mid);
        tree_build(now<<1|1,tree[now].mid+1,r);
        tree[now].dis=(tree[now<<1].dis+tree[now<<1|1].dis)%p;
    }
    
    void tree_do(LL now,LL l,LL r)
    {
        if(tree[now].l==l&&tree[now].r==r)
        {
            if(type==1)
            {
                tree[now].dis=(tree[now].dis*x)%p;
                tree[now].flag=(tree[now].flag*x)%p;
                if(tree[now].if_) tree[now].flag_=(tree[now].flag_*x)%p;
                else
                {
                    tree[now].if_=true;
                    tree[now].flag_=x;
                }
            }
            else if(type==2)
            {
                tree[now].flag=(tree[now].flag+x)%p;
                tree[now].dis=(tree[now].dis+((r-l+1)*x)%p)%p;
            }
            else ans=(ans+tree[now].dis)%p;
            return ;
        }
        if(tree[now].flag||tree[now].if_)
        {
            lc=&tree[now<<1],rc=&tree[now<<1|1];
            if(tree[now].if_)
            {
                lc->dis=(lc->dis*tree[now].flag_)%p;
                rc->dis=(rc->dis*tree[now].flag_)%p;
                lc->flag=(lc->flag*tree[now].flag_)%p;
                rc->flag=(rc->flag*tree[now].flag_)%p;
                if(lc->if_) lc->flag_=(lc->flag_*tree[now].flag_)%p;
                else lc->flag_=tree[now].flag_,lc->if_=true;
                if(rc->if_) rc->flag_=(rc->flag_*tree[now].flag_)%p;
                else rc->flag_=tree[now].flag_,rc->if_=true;
                tree[now].if_=false;
            }
            if(tree[now].flag)
            {
                lc->flag=(lc->flag+tree[now].flag)%p;
                rc->flag=(rc->flag+tree[now].flag)%p;
                lc->dis=(lc->dis+((lc->r-lc->l+1)%p)*tree[now].flag)%p;
                rc->dis=(rc->dis+((rc->r-rc->l+1)%p)*tree[now].flag)%p;
                tree[now].flag=0;
            }
        }
        if(l>tree[now].mid) tree_do(now<<1|1,l,r);
        else if(r<=tree[now].mid) tree_do(now<<1,l,r);
        else
        {
            tree_do(now<<1,l,tree[now].mid);
            tree_do(now<<1|1,tree[now].mid+1,r);
        }
        tree[now].dis=(tree[now<<1].dis+tree[now<<1|1].dis)%p;
    }
    
    int main()
    {
        in(n),in(m),in(p);LL l,r;
        tree_build(1,1,n);
        while(m--)
        {
            in(type),in(l),in(r);
            if(type==1||type==2) in(x),tree_do(1,l,r);
            else
            {
                ans=0;
                tree_do(1,l,r);
                printf("%lld
    ",ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    Redis之数据类型大全
    基于服务的SOA架构
    mybatis_个人总结
    mybatis_开发篇
    mybatis_基础篇
    mybatis_常用标签
    mybatis_映射查询
    solr_架构案例【京东站内搜索】(附程序源代码)
    Solr_全文检索引擎系统
    zabbix监控搭建步骤
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6550490.html
Copyright © 2011-2022 走看看