zoukankan      html  css  js  c++  java
  • LOJ2570 [ZJOI2017]线段树

    传送门

    #include <bits/stdc++.h>
    const int N=800005,W=19;
    typedef long long ll;
    int f[N][W+1],l[N],r[N],sl[N],sr[N],ls[N],rs[N],deep[N],cnt,rt,pos[N],n,Q,u,L,R;
    ll suml[N],sumr[N];
    int build(int fa,int L,int R){
    	int k=++cnt;
    	f[k][0]=fa;
    	l[k]=L,r[k]=R;
    	if (L==R){
    		pos[L]=k;
    		return k;
    	}
    	int mid;
    	scanf("%d",&mid);
    	ls[k]=build(k,L,mid);
    	rs[k]=build(k,mid+1,R);
    	return k;
    }
    int LCA(int x,int y){
    	if (deep[x]<deep[y]) std::swap(x,y);
    	for (int i=W;i>=0;i--)
    		if (deep[f[x][i]]>=deep[y]) x=f[x][i];
    	if (x==y) return x;
    	for (int i=W;i>=0;i--)
    		if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    	return f[x][0];
    }
    void dfs(int x){
    	if (ls[x]){
    		int u=ls[x];
    		deep[u]=deep[x]+1;
    		sl[u]=sl[x]+1;
    		suml[u]=suml[x]+deep[u];
    		sr[u]=sr[x];
    		sumr[u]=sumr[x];
    		dfs(u);
    	}
    	if (rs[x]){
    		int u=rs[x];
    		deep[u]=deep[x]+1;
    		sl[u]=sl[x];
    		suml[u]=suml[x];
    		sr[u]=sr[x]+1;
    		sumr[u]=sumr[x]+deep[u];
    		dfs(u);
    	}
    }
    bool issub(int x,int y){
    	return l[y]<=l[x] && r[x]<=r[y]; 
    }
    ll call(int u,int x){
    	ll ans=suml[x]+(ll)deep[u]*sl[x];
    	int lca=LCA(u,x);
    	ll now=(ll)(sl[x]-sl[lca])*deep[lca];
    	if (issub(u,rs[lca]) && lca!=x) now++;
    	now=now+suml[lca]-sl[lca];
    	return ans-now*2;
    }
    ll calr(int u,int x){
    	ll ans=sumr[x]+(ll)deep[u]*sr[x];
    	int lca=LCA(u,x);
    	ll now=(ll)(sr[x]-sr[lca])*deep[lca];
    	if (issub(u,ls[lca]) && lca!=x) now++;
    	now=now+sumr[lca]-sr[lca];
    	return ans-now*2;
    }
    ll solve(int u,int L,int R){
    	int lca=LCA(L,R);
    	return call(u,L)-call(u,ls[lca])+calr(u,R)-calr(u,rs[lca]);
    }
    int main(){
    	scanf("%d",&n);
    	build(0,1,n);
    	pos[0]=++cnt;
    	f[cnt][0]=cnt+1;//0
    	rt=++cnt;
    	l[rt]=0,r[rt]=n+1;//0-n+1 
    	ls[rt]=pos[0],rs[rt]=cnt+1;
    	cnt++,f[cnt][0]=rt,l[cnt]=1,r[cnt]=n+1;//1-n+1
    	ls[cnt]=1,rs[cnt]=cnt+1;f[1][0]=cnt;
    	cnt++;l[cnt]=r[cnt]=n+1;pos[n+1]=cnt;
    	f[cnt][0]=cnt-1;//n+1-n+1
    	for (int i=1;i<=W;i++)
    		for (int j=1;j<=cnt;j++)
    			f[j][i]=f[f[j][i-1]][i-1];
    	dfs(rt);
    	scanf("%d",&Q);
    	while (Q--){
    		scanf("%d%d%d",&u,&L,&R);
    		L=pos[L-1],R=pos[R+1];
    		printf("%lld
    ",solve(u,L,R));
    	}
    } 
    
    * 生而自由 爱而无畏 *
  • 相关阅读:
    Webdriver启动Firefox浏览器后,页面显示空白
    Windows+Python+Selenium基础篇之1-环境搭建
    office2010无法卸载问题
    .NET使用FastDBF读写DBF
    并发编程相关概念
    C#的多线程简洁笔记
    asp.net core 3.1 入口:Program.cs中的Main函数
    【WPF学习】第四十四章 图画
    .NET知识梳理——1.泛型Generic
    C#个推SDK推送安卓+iOS
  • 原文地址:https://www.cnblogs.com/flyfeather6/p/14381025.html
Copyright © 2011-2022 走看看