• (lazy标记,区间修改与查询) A


    A - A Simple Problem with Integers

    "C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
    "Q a b" means querying the sum of Aa, Aa+1, ... , Ab.

    数据:

    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
    

     AC代码:

    const int maxn=1e5+5;
    ll a[maxn],n,m;
    
    struct Node{
    	ll l,r,su;
    	ll lazy; 
    }tree[maxn<<2+5];
    
    
    void build(ll l,ll r,ll k)
    {
    	tree[k].su=0;
    	tree[k].lazy=0;
    	tree[k].l=l;
    	tree[k].r=r;
    	if(l==r){
    		tree[k].su=a[l];
    		return ;
    	}
    	else{
    		ll mid=(l+r)>>1;
    		build(l,mid,k<<1);
    		build(mid+1,r,k<<1|1);
    		tree[k].su=tree[k<<1].su+tree[k<<1|1].su;
    	}
    }
    
    void down(int k)//k节点lazy标记下传一位 
    {
    	if(tree[k].l==tree[k].r) {
    		//叶子节点
    		//tree[k].su+=tree[k].lazy; 
    		return ;
    	}
    	tree[k<<1].su+=((tree[k<<1].r-tree[k<<1].l+1)*tree[k].lazy);
    	tree[k<<1].lazy+=tree[k].lazy;
    	tree[k<<1|1].su+=((tree[k<<1|1].r-tree[k<<1|1].l+1)*tree[k].lazy);
    	tree[k<<1|1].lazy+=tree[k].lazy;
    	tree[k].lazy=0;
    }
    
    void update(ll l,ll r,ll k,ll p)//区间修改
    {	
    	if(tree[k].l>=l && tree[k].r<=r)//不再往下走,lazy标记 
    	{//lazy表示改点以下的节点还未修改 
    		tree[k].su+=((tree[k].r-tree[k].l+1)*p);
    		tree[k].lazy+=p;
    		return ;
    	}
    	//如果节点区间未被全包含,lazy下传
    	if(tree[k].lazy) down(k); 
    	ll mid=((tree[k].l+tree[k].r)>>1);
    	if(l<=mid) update(l,r,k<<1,p);
    	if(r>mid) update(l,r,k<<1|1,p);
    	tree[k].su=tree[k<<1].su+tree[k<<1|1].su;
    } 
    
    
    ll sum=0;//存区间和 
    void summ(ll l,ll r,ll k)//区间和 
    {
    	if(tree[k].l>=l && tree[k].r<=r)
    	{
    		sum+=tree[k].su;
    		return ;
    	}
    	if(tree[k].lazy) down(k);
    	ll mid=((tree[k].l+tree[k].r)>>1);
    	if(l<=mid)
    		summ(l,r,k<<1);
    	if(r>mid)
    		summ(l,r,k<<1|1);
    }
    /*
    void add(ll n,ll x,ll k)//单点修改
    {
    	if(tree[k].l<=n && n<=tree[k].r)
    	{
    		tree[k].su+=x;
    		if(!(tree[k].l==tree[k].r))
    		{
    			ll mid=(tree[k].l+tree[k].r)>>1;
    			add(n,x,k<<1);
    			add(n,x,k<<1|1);
    		}
    	}
    } 
    */
    int main() 
    {
        scanf("%lld%lld",&n,&m);
        for(ll i=1;i<=n;i++) scanf("%lld",a+i);
      //for(ll i=1;i<=n;i++) scanf("%lld",x),add());//原先代码(超时)
        build(1,n,1);
        char s;
        while(m--)
        {
        	getchar();
        	scanf("%c",&s);
        	ll a,b,c;
        	if(s=='Q')
        	{
        		scanf("%lld%lld",&a,&b);
        		sum=0;
        		summ(a,b,1);
        		printf("%lld
    ",sum);
    		}
    		else{
    			scanf("%lld%lld%lld",&a,&b,&c);
    			update(a,b,1,c);
    		}
    	}
        return 0;
    }
    

      

    ->:一直超时,只要去掉单点修改,在build时就将初始数据加入线段树

      还有读数别用cin...

      void build(ll l,ll r,ll k)
      {
          tree[k].su=0;
          tree[k].lazy=0;
          tree[k].l=l;
          tree[k].r=r;
          if(l==r){
              tree[k].su=a[l];//
              return ;
          }
          else{
              ll mid=(l+r)>>1;
              build(l,mid,k<<1);
              build(mid+1,r,k<<1|1);
              tree[k].su=tree[k<<1].su+tree[k<<1|1].su;//省去单点修改
          }  
      }
    

      

  • 相关阅读:
    三、oracle 体系结构
    js字符串转化为日期及日期判断大小
    二十五、oracle pl/sql进阶控制结构(分支,循环,控制)
    五、oracle 10g目录结构
    二十六、oracle pl/sql 分页
    Oracle物化视图语法
    二、理解over()函数
    Java使用SOAP获取webservice实例解析
    常用的PL/SQL开发原则
    二十九、oracle 触发器
  • 原文地址:https://www.cnblogs.com/liuyongliu/p/10299581.html
Copyright © 2020-2023  润新知