zoukankan      html  css  js  c++  java
  • 线段树

    树状数组就是个辣鸡

    不扯了

    先给链接

    线段树

    皮这么一下我很开心

    线段树区间加

    #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;
    }
    

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

  • 相关阅读:
    129. Sum Root to Leaf Numbers
    113. Path Sum II
    114. Flatten Binary Tree to Linked List
    112. Path Sum
    100. Same Tree
    300. Longest Increasing Subsequence
    72. Edit Distance
    自定义js标签库
    JS 实现Table相同行的单元格自动合并示例代码
    mysql 高版本only_full_group_by 错误
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/8494693.html
Copyright © 2011-2022 走看看