区间更新+区间统计(懒惰标记 模板)——pku3468

前面一直TLE,最终原因是因为没有将查找的压倒O(log(N))
查找更新都需要遗传结构!!!
View Code
#include<stdio.h>

struct data
{
    
int l,r;
    __int64 all;
//开始单点更新
    __int64 hou;
}node[
300009];
int a[100009];

void build(int ll,int rr,int n)
{
    node[n].l
=ll;
    node[n].r
=rr;
    node[n].hou
=0;
    
if(ll==rr)
    {
        node[n].all
=a[rr];
    }
    
    
if (ll==rr) return ;
    
int mid=(ll+rr)>>1;
    build(ll,mid,n
+n);
    build(mid
+1,rr,n+n+1);//先更新下面

    node[n].all
=node[n+n].all+node[n+n+1].all;/////下往上累计

}
void updata(int ll,int rr,int a,int n)
{
    
    
if (ll<=node[n].l&&node[n].r<=rr&&node[n].hou!=-1)
    {
        node[n].hou
+=a;
        node[n].all
+=(node[n].r-node[n].l+1)*a;
        
return ;
    }
    
    
if(node[n].hou)//遗传
    {
        node[n
+n].hou+=node[n].hou;
        node[n
+n].all+=(node[n+n].r-node[n+n].l+1)*node[n].hou;
        node[n
+n+1].hou+=node[n].hou;
        node[n
+n+1].all+=(node[n+n+1].r-node[n+n+1].l+1)*node[n].hou;
        node[n].hou
=0;
    }
    
    
int mid=(node[n].l+node[n].r)>>1;
    
if (rr<=mid) updata(ll,rr,a,n+n);
    
else if (ll>=mid+1) updata(ll,rr,a,n+n+1); 
    
else
    {
        updata(ll,mid,a,n
+n);
        updata(mid
+1,rr,a,n+n+1);
    }
    node[n].all
=node[n+n].all+node[n+n+1].all;//下往上累计
}

__int64 search(
int ll,int rr,int n)
{
    
if(node[n].l==ll&&node[n].r==rr)
    {
        
return node[n].all;
    }

    
if(node[n].hou)//updata时没有更新的遗传
    {
        node[n
+n].hou+=node[n].hou;    
        node[n
+n].all+=(node[n+n].r-node[n+n].l+1)*node[n].hou;  
        node[n
+n+1].hou+=node[n].hou;    
        node[n
+n+1].all+=(node[n+n+1].r-node[n+n+1].l+1)*node[n].hou;
        node[n].hou
=0;
    }

    
int mid=(node[n].l+node[n].r)>>1;
    
if (rr<=mid) return search(ll,rr,n+n);
    
else if (ll>mid) return search(ll,rr,n+n+1); 
    
else
    {
        
return search(ll,mid,n+n)+search(mid+1,rr,n+n+1);
    }
}


int main()
{
    
int L,Q;
    
while(scanf("%d%d",&L,&Q)!=EOF)
    {
        
        
char ss;
        
int i;    
        
        
for(i=1;i<=L;i++)    
        {
            scanf(
"%d",&a[i]);
        }
        build(
1,L,1);

        
while(Q--)
        {
            getchar();
            scanf(
"%c",&ss);
            
            
if(ss=='C')
            {
                
int ll,rr,v;
                scanf(
"%d%d%d",&ll,&rr,&v);
                updata(ll,rr,v,
1);
            }
            
else
            {
                
int ll,rr;
                scanf(
"%d%d",&ll,&rr);
                printf(
"%I64d\n", search(ll,rr,1));
            }
        }
    }
    
return 0;
}

  

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
4
55
9
15
原文地址:https://www.cnblogs.com/huhuuu/p/2106435.html