zoukankan      html  css  js  c++  java
  • 洛谷 P5889 跳树

    大体思路很简单,用线段树维护区间操作,询问便是区间查询即可

    真正有难度的地方在于操作区间合并,比较难理解。

    注意,代码中写的运算符重载只能运用于先进行的操作+后进行的操作

    操作区间合并对我这样的蒟蒻还是挺难理解的

    sys orz.

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #define int long long
    using namespace std;
    const int maxn=5e5+10;
    int n,m,q;
    int max(int a,int b){
        if(a>b)
            return a;
        else
            return b;
    }
    int p[maxn];
    struct node{
    	int fm;
    	int l;
    	int num;
    }tre[maxn*5];
    int k;
    node operator + (node x,node y){
    	node ans=(node){0,0,0};
    	if(!x.fm&&!x.l){
    		return y;
    	}
    	if(!y.fm&&!y.l){
    		return x;
    	}
    	if(x.l>y.fm){
    		ans.fm=x.fm;
    		ans.l=x.l-y.fm+y.l;
    		ans.num=((x.num>>y.fm)<<y.l)+y.num;
    	} 
    	else{
    		ans.fm=x.fm+y.fm-x.l;
    		ans.l=y.l;
    		ans.num=y.num;
    	}
    	return ans;
    }
    void build(int rt,int l,int r){
    	if(l==r){
    		cin>>k;
    		if(k==1){
    			tre[rt].l=1;
    		}
    		else if(k==2){
    			tre[rt].l=1;
    			tre[rt].num=1;
    		}	
    		else if(k==3){
    			tre[rt].fm=1;
    		}
    		return ;
    	}
    	int mid=(l+r)>>1;
    	build(rt*2,l,mid);
    	build(rt*2+1,mid+1,r);
    	tre[rt]=tre[rt*2]+tre[rt*2+1];
    	return ;
    }
    node query(int rt,int l,int r,int ql,int qr){
    	node ans=(node){0,0,0};
    	if(r<ql||l>qr){
    		return ans;
    	}
    	if(l>=ql&&r<=qr){
    		return tre[rt];
    	}
    	int mid=(l+r)>>1;
    	if(ql<=mid){
    		ans=ans+query(rt*2,l,mid,ql,qr);
    	}
    	if(qr>mid){
    		ans=ans+query(rt*2+1,mid+1,r,ql,qr);
    	}
    	return ans;
    }
    void update(int rt,int l,int r,int pos,int x){//??
        if(l==r){
            tre[rt]=(node){0,0,0};
            if(x==1){
                tre[rt].l=1;
            }
            else if(x==2){
                tre[rt].l=1;
                tre[rt].num=1;
            }
            else{
                tre[rt].fm=1;
            }
            return;
        }
        int mid=(l+r)>>1;
        if(pos>mid){
            update(rt*2+1,mid+1,r,pos,x);
        }
        else{
            update(rt*2,l,mid,pos,x);
        }
        tre[rt]=tre[rt*2]+tre[rt*2+1];
    }
    signed main(){
    //	freopen("a.in","r",stdin);
    	cin>>n>>m>>q;
    	//cout<<n<<m<<q;
    	build(1,1,m);
    	int t;
    	node x;
    	while(q--){
    		cin>>t;
    		if(t==1){
    			int ll,rr,s;
    			cin>>s>>ll>>rr;
    			x=query(1,1,m,ll,rr);
    	//		cout<<x.fm<<" "<<x.l<<" "<<x.num<<endl;
    			cout<<((max(1,s>>x.fm))<<x.l)+x.num<<endl;	
    		}
    		if(t==2){
    			int d,y;
    			cin>>d>>y;
    			update(1,1,m,d,y);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    DOM-DOMTree-查找

    用sql语句操作数据库
    数据查询基础
    【案例】城市地址三级联动
    【案例】城市地址二级联动
    【案例】高仿百度注册页
    【案例】自由运动小球
    【案例】使用上下左右键控制元素的移动
    事件
  • 原文地址:https://www.cnblogs.com/rpup/p/13903556.html
Copyright © 2011-2022 走看看