zoukankan      html  css  js  c++  java
  • [LNOI 2014] LCA

    题目传送-Luogu4211

    题目传送-BZOJ3626

    题意:

    给你一棵(n)个节点的树,定义一个点的深度为它到1号节点的距离+1
    (q)次询问,每次给出((l,r,p)),求(sum_{i=l}^rdep(LCA(i,p)))

    题解:

    考虑计算LCA(x,y),我们把x->1经过的节点权值+1,那么答案就是y->1经过的权值和,这东西可以前缀一下,然后答案就是(sum_r-sum_{l-1})
    这个可以用离线+树剖搞出来

    过程:

    树剖写错了O(1)次
    还忘了取模。。

    代码:

    const int N=50010;
    const int P=201314;
    int n,m;
    namespace SHU {
    	int head[N],nxt[N<<1],to[N<<1],lst=0;
    	inline void adde(int x,int y) {
    		nxt[++lst]=head[x]; to[lst]=y; head[x]=lst;
    	}
    	int fa[N],dep[N],sz[N],son[N],top[N],s_t[N],t_s[N],ind=0;
    	void dfs1(int u) {
    		sz[u]=1;
    		int pos=-1;
    		for(int i=head[u];i;i=nxt[i]) {
    			int v=to[i];
    			dep[v]=dep[u]+1;
    			dfs1(v);
    			sz[u]+=sz[v];
    			if(pos==-1 || sz[pos]<sz[v]) pos=v;
    		}
    		son[u]=pos;
    	}
    	void dfs2(int u) {
    		// printf("u=%d
    ",u);
    		t_s[u]=++ind; s_t[ind]=u;
    		if(son[u]!=-1) {
    			top[son[u]]=top[u];
    			dfs2(son[u]);
    		}
    		for(int i=head[u];i;i=nxt[i])
    			if(to[i]!=son[u]) {
    				int v=to[i];
    				top[v]=v;
    				dfs2(v);
    			}
    	}
    	inline void Init() {
    		fa[1]=0; dep[0]=0;
    		dep[1]=1; top[1]=1;
    		dfs1(1); dfs2(1);
    	}
    	#define lc (u<<1)
    	#define rc (lc|1)
    	#define left lc,l,mid
    	#define right rc,mid+1,r
    	#define mid ((l+r)>>1)
    	#define root 1,1,n
    	const int ALL=N<<2;
    	int val[ALL],laz[ALL];
    	inline void Update(int u,int l,int r,int v) {
    		(laz[u]+=v)%=P; (val[u]+=v*(r-l+1)%P)%=P;
    	}
    	inline void Push_Dn(int u,int l,int r) {
    		if(laz[u]) {
    			Update(left,laz[u]);
    			Update(right,laz[u]);
    			laz[u]=0;
    		}
    	}
    	void modify(int u,int l,int r,int L,int R,int v) {
    	// 	assert(L<=R);
    	// 	printf("%d %d %d %d %d %d
    ",u,l,r,L,R,v);
    		if(L<=l && r<=R) {
    			Update(u,l,r,v); return;
    		}
    		Push_Dn(u,l,r);
    		if(L<=mid) modify(left,L,R,v);
    		if(R> mid) modify(right,L,R,v);
    		val[u]=(val[lc]+val[rc])%P;
    	}
    	int query(int u,int l,int r,int L,int R) {
    		if(L<=l && r<=R) return val[u];
    		Push_Dn(u,l,r);
    		int ret=0;
    		if(L<=mid) ret+=query(left,L,R);
    		if(R> mid) ret+=query(right,L,R);
    		return ret%P;
    	}
    	inline void Modify(int u) {
    		while(dep[top[u]]!=0) {
    			// printf("Modify::%d %d
    ",u,top[u]);
    			modify(root,t_s[top[u]],t_s[u],1);
    			u=fa[top[u]];
    		}
    		// printf("val=%d
    ",val[1]);
    	}
    	inline int Query(int u) {
    		int ret=0;
    		while(dep[top[u]]!=0) {
    			ret=(ret+query(root,t_s[top[u]],t_s[u]))%P;;
    			// printf("%d %d %d
    ",u,top[u],ret);
    			u=fa[top[u]];
    		}
    		return ret;
    	}
    }
    struct QUERY {
    	int l,r,p,ans;
    	inline void in() {
    		read(l); read(r); read(p); ++l; ++r; ++p;
    	}
    }a[N];
    struct STA {
    	int p,u,id,type;
    	bool operator < (const STA &a)const {
    		return p<a.p || (p==a.p && u<a.u);
    	}
    }q[N<<1]; int ind=0;
    signed main() {
    	// freopen("3.in","r",stdin);
    	// freopen("my.out","w",stdout);
    	read(n); read(m);
    	for(int i=2;i<=n;i++) {
    		read(SHU::fa[i]); ++SHU::fa[i];
    		SHU::adde(SHU::fa[i],i);
    	}
    	SHU::Init();
    	for(int i=1;i<=m;i++) {
    		a[i].in();
    		q[++ind]=(STA) {a[i].l-1,a[i].p,i,-1};
    		q[++ind]=(STA) {a[i].r  ,a[i].p,i, 1};
    	}
    	sort(q+1,q+ind+1);
    	int cur=1;
    	while(q[cur].p==0 && cur<=ind) ++cur;
    	for(int i=1;i<=n;i++) {
    		// printf("i=%d
    ",i);
    		SHU::Modify(i);
    		while(q[cur].p==i && cur<=ind) {
    			(a[q[cur].id].ans+=q[cur].type*SHU::Query(q[cur].u))%=P;
    			// printf("%d
    ",a[q[cur].id].ans);
    			++cur;
    		}
    	}
    	for(int i=1;i<=m;i++) {
    		printf("%d
    ",(a[i].ans+P)%P);
    	}
    	return 0;
    }
    

    用时:1h

  • 相关阅读:
    数据结构(三)栈与递归
    机器学习(二)------ 回归
    数据结构(二)线性表
    数据结构(一)数据结构基础
    机器学习 (一)------分类
    操作系统概述
    NumPy函数库基础
    总线与输入输出子系统
    FT VIEW SE高效开发之全局对象
    STUDIO 5000 V32新CRACK和新功能
  • 原文地址:https://www.cnblogs.com/functionendless/p/9546803.html
Copyright © 2011-2022 走看看