码迷,mamicode.com
首页 > 其他好文 > 详细

线段树

时间:2018-03-02 20:39:24      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:+=   new   www   end   src   tar   info   build   线段   

树状数组就是个辣鸡

技术分享图片

不扯了

先给链接

线段树

皮这么一下我很开心

线段树区间加

#include<iostream>
using namespace std;
struct node
{
    long long val;
    long long tag;
}tree[10000000];
long long in[10000000];
void build(long long root,long long start,long long end)
{
    tree[root].tag=0;
    if(start==end)
    {
        tree[root].val=in[start];
        return ;
    }
    long long mid=(start+end)/2;
    build(root*2,start,mid);
    build(root*2+1,mid+1,end);
    tree[root].val=tree[root*2].val+tree[root*2+1].val;
    return ;
}
void push(long long root,long long start,long long end,long long mid)
{
    if(tree[root].tag)
    {
        tree[root*2].tag+=tree[root].tag;
        tree[root*2+1].tag+=tree[root].tag;
        tree[root*2].val+=tree[root].tag*(mid-start+1);
        tree[root*2+1].val+=tree[root].tag*(end-mid);
        tree[root].tag=0;
    }
    return ;
}
void update(long long root,long long nstart,long long nend,long long ustart,long long uend,long long add) // cymbal
{
    if(nstart>uend||nend<ustart)
    {
        return ;
    }
    if(nstart>=ustart&&nend<=uend)
    {
        tree[root].tag+=add;
        tree[root].val+=add*(nend-nstart+1);
        return ;
    }
    long long mid=(nstart+nend)/2;
    push(root,nstart,nend,mid);
    update(root*2,nstart,mid,ustart,uend,add);
    update(root*2+1,mid+1,nend,ustart,uend,add);
    tree[root].val=tree[root*2].val+tree[root*2+1].val;
    return ;
}
long long check(long long root,long long nstart,long long nend,long long ustart,long long uend)
{
    if(nstart>uend||nend<ustart)
    {
        return 0;
    }
    if(nstart>=ustart&&nend<=uend)
    {
        return tree[root].val;
    }
    long long mid=(nstart+nend)/2;
    push(root,nstart,nend,mid);
    long long cym=check(root*2,nstart,mid,ustart,uend)
          +check(root*2+1,mid+1,nend,ustart,uend);
    return cym;
}
int main()
{
    cin.sync_with_stdio(false);
    long long l,m;
    cin>>l>>m;
    for(long long i=1;i<=l;i++)
        cin>>in[i];
    long long a,b;
    long long f,k;
    build(1,1,l);
    for(long long i=1;i<=m;i++)
    {
        cin>>f>>a>>b;
        if(f==1)
        {
            cin>>k;
            update(1,1,l,a,b,k);
        }
        if(f==2)
            cout<<check(1,1,l,a,b)<<endl;
    }
    return 0;
}

因为是区间加,在push懒标记时和要加上区间长度*懒标记

如果时区间大小的话就不用le。要根据实际情况设计push函数

在看一道区间乘和加的题

题目,顺便%%%RQY

这道题告诉了我们如何处理两种运算的关系
(如果不知到的话,看看洛谷题解就行了,洛谷还是很好的网站,最起码,它不baoza

#include<iostream>
using namespace std;
struct node
{
    long long val;
    long long tag1;//*
    long long tag2;//+
    node(){val=0;tag1=1;tag2=0;}
};
node tree[400000];
long long in[100010];
long long n,m,p;
void build(long long root,long long left,long long right)
{
    if(left==right)
    {
        tree[root].val=in[left]%p;
        return ;
    }
    long long mid=(left+right)/2;
    build(root*2,left,mid);
    build(root*2+1,mid+1,right);
    tree[root].val=tree[root*2].val+tree[root*2+1].val;
    tree[root].val%=p;
    return ;
}
void push_down(long long root,long long left,long long right,long long mid)
{
    tree[root*2].val=((tree[root*2].val*tree[root].tag1)%p+tree[root].tag2*(mid-left+1))%p;
    tree[root*2].tag1=(tree[root*2].tag1*tree[root].tag1)%p;
    tree[root*2].tag2=(tree[root*2].tag2*tree[root].tag1+tree[root].tag2)%p;
    tree[root*2+1].val=((tree[root*2+1].val*tree[root].tag1)%p+tree[root].tag2*(right-mid))%p;
    tree[root*2+1].tag1=(tree[root*2+1].tag1*tree[root].tag1)%p;
    tree[root*2+1].tag2=(tree[root*2+1].tag2*tree[root].tag1+tree[root].tag2)%p;
    tree[root].tag1=1;
    tree[root].tag2=0;
}
void updata1(long long root,long long nleft,long long nright,long long aleft,long long aright,long long value)
{
    if(nleft>aright||nright<aleft)
        return ;
    if(nleft>=aleft&&nright<=aright)
    {
        tree[root].val=(tree[root].val*value)%p;
        tree[root].tag1=(tree[root].tag1*value)%p;
        tree[root].tag2=(tree[root].tag2*value)%p;
        return ;
    }
    long long mid=(nleft+nright)/2;
    push_down(root,nleft,nright,mid);
    updata1(root*2,nleft,mid,aleft,aright,value);
    updata1(root*2+1,mid+1,nright,aleft,aright,value);
    tree[root].val=(tree[root*2].val+tree[root*2+1].val)%p;
    return ;
}
void updata2(long long root,long long nleft,long long nright,long long aleft,long long aright,long long value)
{
    if(nleft>aright||nright<aleft)
        return ;
    if(nleft>=aleft&&nright<=aright)
    {
        tree[root].val=(tree[root].val+value*(nright-nleft+1))%p;
        tree[root].tag2=(tree[root].tag2+value)%p;
        return ;
    }
    long long mid=(nleft+nright)/2;
    push_down(root,nleft,nright,mid);
    updata2(root*2,nleft,mid,aleft,aright,value);
    updata2(root*2+1,mid+1,nright,aleft,aright,value);
    tree[root].val=(tree[root*2].val+tree[root*2+1].val)%p;
    return ;
}
long long check(long long root,long long nleft,long long nright,long long aleft,long long aright)
{
    if(nleft>aright||nright<aleft)
        return 0;
    if(nleft>=aleft&&nright<=aright)
        return tree[root].val;
    long long mid=(nleft+nright)/2;
    push_down(root,nleft,nright,mid);
    long long ans=(
            check(root*2,nleft,mid,aleft,aright)+
            check(root*2+1,mid+1,nright,aleft,aright)
           )%p;
    return ans;
}
int main() 
{
    cin.sync_with_stdio(false);
    cin>>n>>m>>p;
    for(long long i=1;i<=n;i++)
        cin>>in[i];
    build(1,1,n);
    long long a,b,c,d;
    for(long long i=1;i<=m;i++)
    {
        cin>>a;
        switch(a)
        {
            case 1:
                    cin>>b>>c>>d;
                    updata1(1,1,n,b,c,d);
                    break;
            case 2:
                    cin>>b>>c>>d;
                    updata2(1,1,n,b,c,d);
                    break;
            case 3:
                    cin>>b>>c;
                    cout<<check(1,1,n,b,c)<<endl;
                    break;
        }
    }    
    return 0;
}

同时也要注意数据范围,我就是载在了上面。

线段树

标签:+=   new   www   end   src   tar   info   build   线段   

原文地址:https://www.cnblogs.com/Lance1ot/p/8494693.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!