zoukankan      html  css  js  c++  java
  • P3373 【模板】线段树 2

    题目描述

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

    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<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int N=1e5+5;
    
    int p;
    long long a[N];
    struct Tree
    {
        int l,r,mid;
        long long v,mul,add;
    }tree[N<<2];
    
    void build(int root,int l,int r)
    {
        tree[root].l=l,tree[root].r=r,tree[root].mid=l+r>>1,tree[root].mul=1;
        if(l==r)
        {
            tree[root].v=a[l];
            return;
        }
        build(root<<1,l,tree[root].mid);
        build(root<<1|1,tree[root].mid+1,r);
        tree[root].v=tree[root<<1].v+tree[root<<1|1].v;
        tree[root].v%=p;
        return;
    }
    
    void push_down(int root)
    {
        tree[root<<1].v=(tree[root<<1].v*tree[root].mul+tree[root].add*(tree[root].mid-tree[root].l+1))%p;
        tree[root<<1|1].v=(tree[root<<1|1].v*tree[root].mul+tree[root].add*(tree[root].r-tree[root].mid))%p;
        tree[root<<1].mul=(tree[root<<1].mul*tree[root].mul)%p;
        tree[root<<1|1].mul=(tree[root<<1|1].mul*tree[root].mul)%p;
        tree[root<<1].add=(tree[root<<1].add*tree[root].mul+tree[root].add)%p;
        tree[root<<1|1].add=(tree[root<<1|1].add*tree[root].mul+tree[root].add)%p;
        tree[root].add=0;
        tree[root].mul=1;
        return;
    }
    
    void update1(int root,int l,int r,long long k)
    {
        if(r<tree[root].l||tree[root].r<l)
            return;
        if(l<=tree[root].l&&tree[root].r<=r)
        {
            tree[root].v=(tree[root].v*k)%p;
            tree[root].mul=(tree[root].mul*k)%p;
            tree[root].add=(tree[root].add*k)%p;
            return;
        }
        push_down(root);
        update1(root<<1,l,r,k);
        update1(root<<1|1,l,r,k);
        tree[root].v=(tree[root<<1].v+tree[root<<1|1].v)%p;
        return;
    }
    
    void update2(int root,int l,int r,long long k)
    {
        if(r<tree[root].l||tree[root].r<l)
            return;
        if(l<=tree[root].l&&tree[root].r<=r)
        {
            tree[root].add=(tree[root].add+k)%p;
            tree[root].v=(tree[root].v+k*(tree[root].r-tree[root].l+1))%p;
            return;
        }
        push_down(root);
        update2(root<<1,l,r,k);
        update2(root<<1|1,l,r,k);
        tree[root].v=(tree[root<<1].v+tree[root<<1|1].v)%p;
        return;
    }
    
    long long query(int root,int l,int r)
    {
        if(r<tree[root].l||tree[root].r<l)
            return 0;
        if(l<=tree[root].l&&tree[root].r<=r)
            return tree[root].v;
        push_down(root);
        return (query(root<<1,l,r)+query(root<<1|1,l,r))%p;
    }
    
    int main()
    {
        int n,m;
        scanf("%d%d%d",&n,&m,&p);
        for(int i=1;i<=n;++i)
            scanf("%lld",&a[i]);
        build(1,1,n);
        int type;
        int l,r;
        long long k;
        while(m--)
        {
            scanf("%d",&type);
            if(type==1)
            {
                scanf("%d%d%lld",&l,&r,&k);
                update1(1,l,r,k);
            }
            else if(type==2)
            {
                scanf("%d%d%lld",&l,&r,&k);
                update2(1,l,r,k);
            }
            else
            {
                scanf("%d%d",&l,&r);
                printf("%lld
    ",query(1,l,r));
            }
        }
        return 0;
    }
  • 相关阅读:
    C#获取IP信息
    获取百度地图按条件查找的信息
    react中如何实现一个按钮的动态隐藏和显示(有效和失效)
    es6 关于map和for of的区别有哪些?
    js 高级程序设计 第四章学习笔记
    ant design Table合并单元格合并单元格怎么用?
    React中如何实现模态框每次打开都是初始界面
    前端界面布局相关整理之2017
    待改善的代码整理
    cq三期备注说明
  • 原文地址:https://www.cnblogs.com/lovewhy/p/9633502.html
Copyright © 2011-2022 走看看