• 用指针写线段树(维护乘法)


    今天肖神给我讲课,讲了一个用指针写的线段树,写起来比数组复杂,但是貌似动态开点操作好像简单一些。之前我也写过用指针的数据结构,所以理解起来不是很难。

    题目描述
    
    如题,已知一个数列,你需要进行下面三种操作:
    
    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、240 mod 38=2

    直接写代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(int i = a;i <= n;i++)
    typedef long long ll;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(),c > '9' || c < '0')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(),c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op == 1)
            x = -x;
    }
    struct node
    {
        node *lch,*rch;
        int sum,mul,add;
        node()
        {
            lch = 0;
            rch = 0;
            mul = 1;
            add = 0;
        }
    }*root;
    int n,m,p,a[100010];
    void update(node *u)
    {
        u->sum = (u->lch->sum + u->rch->sum) % p;
    }
    void build(node *&u,int l,int r)
    {
        u = new node;
        if(l == r)
        {
            u->sum = a[l];
            return;
        }
        int mid = (l + r) >> 1;
        build(u->lch,l,mid);
        build(u->rch,mid + 1,r);
        update(u);
    }
    void refresh(node *u,int l,int r,int mul,int add)
    {
        u->sum = (ll)u->sum * mul % p;
        u->sum = (u->sum + (ll)add * (r - l + 1)) % p;
        u->mul = (ll)u->mul * mul % p;
        u->add = ((ll)u->add * mul + add) % p;
    }
    void push_down(node *u,int l,int r)
    {
        if(u->mul != 1 || u->add != 0)
        {
            int mid = (l + r) >> 1;
            refresh(u->lch,l,mid,u->mul,u->add);
            refresh(u->rch,mid + 1,r,u->mul,u->add);
            u->mul = 1;
            u->add = 0;
        }
    }
    void modify(node *u,int l,int r,int ql,int qr,int mul,int add)
    {
        if(l == ql && r == qr)
        {
            refresh(u,l,r,mul,add);
            return;
        }
        push_down(u,l,r);
        int mid = (l + r) >> 1;
        if(qr <= mid)
        {
            modify(u->lch,l,mid,ql,qr,mul,add);
        }
        else if(ql > mid)
        {
            modify(u->rch,mid + 1,r,ql,qr,mul,add);
        }
        else
        {
            modify(u->lch,l,mid,ql,mid,mul,add);
            modify(u->rch,mid + 1,r,mid + 1,qr,mul,add);
        }
        update(u);
    }
    int query(node *u,int l,int r,int ql,int qr)
    {
        if(l == ql && r == qr)
        {
            return u->sum;
        }
        push_down(u,l,r);
        int mid = (l + r) >> 1;
        if(qr <= mid)
        {
            return query(u->lch,l,mid,ql,qr);
        }
        else if(ql > mid)
        {
            return query(u->rch,mid + 1,r,ql,qr);
        }
        else
        {
            return (query(u->lch,l,mid,ql,mid) + query(u->rch,mid + 1,r,mid + 1,qr)) % p;
        }
    }
    int main()
    {
        read(n);read(m);read(p);
        duke(i,1,n)
            read(a[i]);
        build(root,1,n);
        int op,l,x,r;
        while(m--)
        {
            read(op);read(l);read(r);
            if(op == 1)
            {
                read(x);
                modify(root,1,n,l,r,x,0);
            }
            else if(op == 2)
            {
                read(x);
                modify(root,1,n,l,r,1,x);
            }
            else
            {
                printf("%d
    ",query(root,1,n,l,r));
            }
        }
        return 0;
    }
  • 相关阅读:
    LINQ Provider表达式树6
    asp.net Forms 验证No.3
    三种用户验证No.1 asp.net Forms
    LinQ表达式目录2
    将ASP.NET MVC 2.0 部署在IIS6和IIS7上
    LINQ Provider 表达式树 5
    asp.net Forms验证No.2
    LINQ表达式树4
    LINQ表达式树3
    绝对精华win8如何使用,玩转win8看完绝不后悔
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9427122.html
Copyright © 2020-2023  润新知