zoukankan      html  css  js  c++  java
  • (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;//省去单点修改
          }  
      }
    

      

  • 相关阅读:
    【LeetCode】17. Letter Combinations of a Phone Number
    【LeetCode】16. 3Sum Closest
    【LeetCode】15. 3Sum 三个数和为0
    【LeetCode】14. Longest Common Prefix 最长前缀子串
    【LeetCode】13. Roman to Integer 罗马数字转整数
    【LeetCode】12. Integer to Roman 整型数转罗马数
    【LeetCode】11. Container With Most Water
    【LeetCode】10. Regular Expression Matching
    Models of good programmer
    RSA Algorithm
  • 原文地址:https://www.cnblogs.com/liuyongliu/p/10299581.html
Copyright © 2011-2022 走看看