zoukankan      html  css  js  c++  java
  • 【CodeChef COT5】—Count on a Treap(线段树维护单调栈)

    传送门


    考虑如果按照键值排序
    那么2个点的lcalca就是他们中间valval最大的点

    找到lcalca后就只需要考虑怎么统计一个点到根的距离

    实际上一个点到根的距离是分别往左往右的最长上升子序列的长度和

    证明的话是显然的
    考虑一个点uu,如果vvuu往某个方向的最长上升序列上
    那么vv一定是[u,v][u,v]之间的最大值
    所以Lca(u,v)=vLca(u,v)=v,所以vv一定在uu到根的路径上

    动态维护最长上升子序列可以参照BZOJ2957BZOJ2957

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ob==ib)?EOF:*ib++;
    }
    #define gc getchar
    #define int unsigned int
    inline int read(){
        char ch=gc();
        int res=0,f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    #define ll long long
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define cs const
    const int mod=1e9+7;
    inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
    inline void Add(int &a,int b){a=add(a,b);}
    inline int dec(int a,int b){return a>=b?a-b:a-b+mod;}
    inline void Dec(int &a,int b){a=dec(a,b);}
    inline int mul(int a,int b){return 1ll*a*b>=mod?1ll*a*b%mod:a*b;}
    inline void Mul(int &a,int b){a=mul(a,b);}
    inline int ksm(int a,int b,int res=1){for(;b;b>>=1,a=mul(a,a))(b&1)?(res=mul(res,a)):0;return res;}
    inline void chemx(int &a,int b){a<b?a=b:0;}
    inline void chemn(int &a,int b){a>b?a=b:0;}
    cs int N=200005;
    int n,m,tw[N<<1],a[N<<1];
    struct opt{
    	int op,k,w;
    }q[N];
    namespace seg{
    	int mx[N<<2],sl[N<<2],sr[N<<2],mxp[N<<2];
    	#define lc (u<<1)
    	#define rc ((u<<1)|1)
    	#define mid ((l+r)>>1)
    	inline int queryL(int u,int l,int r,int k){
    		if(l==r)return mx[u]>=k;
    		if(mx[lc]<k)return queryL(rc,mid+1,r,k);
    		return sl[u]-sl[lc]+queryL(lc,l,mid,k);
    	}
    	inline int queryR(int u,int l,int r,int k){
    		if(l==r)return mx[u]>=k;
    		if(mx[rc]<k)return queryR(lc,l,mid,k);
    		return sr[u]-sr[rc]+queryR(rc,mid+1,r,k);
    	}
    	inline void pushup(int u,int l,int r){
    		if(mx[lc]>mx[rc])mx[u]=mx[lc],mxp[u]=mxp[lc];
    		else mx[u]=mx[rc],mxp[u]=mxp[rc];
    		sl[u]=sl[lc]+queryL(rc,mid+1,r,mx[lc]);
    		sr[u]=sr[rc]+queryR(lc,l,mid,mx[rc]);
    	}
    	inline void update(int u,int l,int r,int p,int k){
    		if(l==r){mx[u]=k,mxp[u]=l,sl[u]=sr[u]=1;return;}
    		if(p<=mid)update(lc,l,mid,p,k);
    		else update(rc,mid+1,r,p,k);
    		pushup(u,l,r);
    	}
    	inline void delet(int u,int l,int r,int p){
    		if(l==r){mx[u]=0,mxp[u]=0,sl[u]=sr[u]=0;return;}
    		if(p<=mid)delet(lc,l,mid,p);
    		else delet(rc,mid+1,r,p);
    		pushup(u,l,r);
    	}
    	inline pii query(int u,int l,int r,int st,int des){
    		if(st<=l&&r<=des)return pii(mx[u],mxp[u]);
    		if(des<=mid)return query(lc,l,mid,st,des);
    		if(mid<st)return query(rc,mid+1,r,st,des);
    		pii vl=query(lc,l,mid,st,des),vr=query(rc,mid+1,r,st,des);
    		return vl.fi>vr.fi?vl:vr;
    	}
    	inline pii qryL(int u,int l,int r,int st,int des,int k){
    		if(st<=l&&r<=des)return pii(max(mx[u],k),queryL(u,l,r,k));
    		if(des<=mid)return qryL(lc,l,mid,st,des,k);
    		if(mid<st)return qryL(rc,mid+1,r,st,des,k);
    		pii vl=qryL(lc,l,mid,st,des,k);
    		pii vr=qryL(rc,mid+1,r,st,des,vl.fi);
    		return pii(max(vl.fi,vr.fi),vl.se+vr.se);
    	}
    	inline pii qryR(int u,int l,int r,int st,int des,int k){
    		if(st<=l&&r<=des)return pii(max(mx[u],k),queryR(u,l,r,k));
    		if(des<=mid)return qryR(lc,l,mid,st,des,k);
    		if(mid<st)return qryR(rc,mid+1,r,st,des,k);
    		pii vl=qryR(rc,mid+1,r,st,des,k);
    		pii vr=qryR(lc,l,mid,st,des,vl.fi);
    		return pii(max(vl.fi,vr.fi),vl.se+vr.se);
    	}
    	inline int dis(int u){
    		int res=0;
    		if(u<m)res+=qryL(1,1,m,u+1,m,tw[u]).se;
    		if(1<u)res+=qryR(1,1,m,1,u-1,tw[u]).se;
    		return res;
    	}
    	inline int ask(int ku,int kv){
    		if(ku>kv)swap(ku,kv);
    		int pos=query(1,1,m,ku,kv).se;
    		return dis(ku)+dis(kv)-2*dis(pos);
    	}
    }; 
    signed main(){
    	n=read();
    	for(int i=1;i<=n;i++){
    		int op=read(),k=read(),w;q[i].op=op,q[i].k=k;
    		a[++m]=k;
    		if(op!=1)
    			w=read(),q[i].w=w,a[++m]=w;
    	}
    	sort(a+1,a+m+1);
    	m=unique(a+1,a+m+1)-a-1;
    	for(int i=1;i<=n;i++){
    		q[i].k=lower_bound(a+1,a+m+1,q[i].k)-a;
    		if(q[i].op!=1)q[i].w=lower_bound(a+1,a+m+1,q[i].w)-a;
    	}
    	for(int i=1;i<=n;i++){
    		int op=q[i].op,k=q[i].k,w=q[i].w;
    		if(op==0){
    			seg::update(1,1,m,k,w),tw[k]=w;
    		}
    		if(op==1){
    			seg::delet(1,1,m,k);
    		}
    		if(op==2){
    			cout<<seg::ask(k,w)<<'
    ';
    		}
    	}
    }
    
  • 相关阅读:
    css技巧和经验列表
    CSS3嵌入字体@font-face调用字体
    新闻列表单行滚动(多行显示)简洁向上滚动js效果
    打破构图的平衡!增强设计感染力
    何以双十(补昨天)
    MySQL5.7 基于二进制包的安装
    Nginx Log日志统计分析常用命令
    MySQL错误代码大全
    MVC4中的Display Mode简介
    ReadOnly关键字修饰的变量可以修改,只是不能重新分配
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328609.html
Copyright © 2011-2022 走看看