zoukankan      html  css  js  c++  java
  • HDU 4027——线段树加奇怪的lazy

    一看就是成段更新需要lazy,使劲一个一个更新肯定是不行的。。。

    思路是判断要不要更新每个区间,有的时候是不需要更新的,然后标记成lazy以后不更新就好了。。

    之前一直不是很理解lazy还是,现在也是略懂状态。。总之继续努力吧。。蒟蒻。。

    #include<stdio.h>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    using namespace std;
    const int MAX=1000000;
    struct pr {
        long long sum;
        int lazy;
        int left,right;					//对应区间,注意区别rr,ll
    }tr[MAX+10];
    int n;
    inline int ll(int k) {return 2*k;} 		 //左边的下标
    inline int rr(int k) {return 2*k+1;}		 //右边的下标
    inline int mid(int kk1,int kk2) {return (kk1+kk2)>>1;}
    
    void pushdown(int k) {
        if (tr[k].lazy==0) {							
            int l=tr[k].left,r=tr[k].right;
            if(tr[k].sum==(r-l+1)){		
                tr[k].lazy=1;
            }
        }
    }
    
    void build(int k,int s,int t) {
        tr[k].left=s;tr[k].right=t;
        if(s==t) {scanf("%lld",&tr[k].sum);return;}				//开始最下面是多少
        build(ll(k),s,mid(s,t));
        build(rr(k),mid(s,t)+1,t);
        tr[k].sum=tr[ll(k)].sum+tr[rr(k)].sum;		
    }
    
    void modify(int k,int s,int t) {
        int l=tr[k].left,r=tr[k].right;
        if(tr[k].lazy&&s==l&&r==t){
            return ;
        }
        if(l==r){
            tr[k].sum=(long long)(floor(sqrt(tr[k].sum)+1e-5));
            return ;
        }
        int mi=mid(l,r);
        if(t<=mi) modify(ll(k),s,t);
        else if(s>mi) modify(rr(k),s,t);
        else {
            modify(ll(k),s,mi);
            modify(rr(k),mi+1,t);
        }
        tr[k].sum=tr[ll(k)].sum+tr[rr(k)].sum;
        pushdown(k);
    }
    long long query(int k,int s,int t) {
        int l=tr[k].left,r=tr[k].right;
        if(l==s&&r==t) return tr[k].sum;
        int mi=mid(l,r);
        long long res=0;
        if (t<=mi) res+=query(ll(k),s,t);
        else if(s>mi) res+=query(rr(k),s,t);
        else res+=(query(ll(k),s,mi)+query(rr(k),mi+1,t));
        return res;
    }
    int main()
    {
        int ii=1;
        while(cin>>n){
    
            memset(tr,0,sizeof(tr));
            build(1,1,n);
            cout<<"Case #"<<ii++<<":"<<endl;
            int m;
            cin>>m;
            int a,b,c;
            for(int i=0;i<m;i++){
                scanf("%d%d%d",&a,&b,&c);
                if(b>c)
                    swap(b,c);
                if(a==0){
                    modify(1,b,c);
                }
                else
                    cout<<query(1,b,c)<<endl;
            }
            cout<<endl;
        }
        return 0;
    }
    



  • 相关阅读:
    动态规划 ------最短路径问题
    回溯算法 ------回溯算法的设计思想和适用条件
    回溯算法 ------ 回溯算法的设计思想及适用条件
    回溯算法 ------回溯算法的几个例子
    纯css实现翻书效果
    从vue源码看props
    js循环中使用async/await踩过的坑
    js实现word转换为html
    从vue源码看Vue.set()和this.$set()
    微信、qq二次分享
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672590.html
Copyright © 2011-2022 走看看