• CF893F Subtree Minimum Query


    题目

    这不线段树合并板子题吗

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define LL long long
    #define re register
    #define maxn 100005
    #define inf 9999999999
    inline int read() {
    	char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    inline int max(int a,int b) {return a>b?a:b;}
    inline int min(int a,int b) {return a<b?a:b;}
    struct E{int v,nxt;}e[maxn<<1];
    int l[maxn*40],r[maxn*40],mx[maxn*40];
    int tot,rt[maxn];
    int n,ro,head[maxn],num,md,deep[maxn],a[maxn];
    inline void add(int x,int y) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;}
    void dfs(int x) {
    	md=max(md,deep[x]);
    	for(re int i=head[x];i;i=e[i].nxt) {
    		if(deep[e[i].v]) continue;
    		deep[e[i].v]=deep[x]+1;
    		dfs(e[i].v);
    	}
    }
    inline void pushup(int now) {mx[now]=min(mx[l[now]],mx[r[now]]);}
    int change(int now,int x,int y,int pos,int val) {
    	if(!now) now=++tot,mx[now]=inf;
    	if(x==y) {mx[now]=min(mx[now],val);return now;}
    	int mid=x+y>>1;
    	if(pos<=mid) l[now]=change(l[now],x,mid,pos,val);
    		else r[now]=change(r[now],mid+1,y,pos,val);
    	pushup(now);return now;
    }
    int merge(int a,int b,int x,int y) {
    	if(!a) return b;if(!b) return a;
    	int now=++tot;
    	if(x==y) {mx[now]=min(mx[a],mx[b]);return now;}
    	int mid=x+y>>1;
    	l[now]=merge(l[a],l[b],x,mid),r[now]=merge(r[a],r[b],mid+1,y);
    	pushup(now);return now;
    }
    int query(int now,int x,int y,int lx,int ry) {
    	if(!now) return inf;
    	if(x<=lx&&y>=ry) return mx[now];
    	int mid=lx+ry>>1;
    	if(y<=mid) return query(l[now],x,y,lx,mid);
    	if(x>mid) return query(r[now],x,y,mid+1,ry);
    	return min(query(l[now],x,y,lx,mid),query(r[now],x,y,mid+1,ry));
    }
    void Dfs(int x) {
    	for(re int i=head[x];i;i=e[i].nxt) {
    		if(deep[e[i].v]<deep[x]) continue;
    		Dfs(e[i].v);
    		rt[x]=merge(rt[x],rt[e[i].v],1,md);
    	}
    }
    int main() {
    	n=read(),ro=read();
    	for(re int i=1;i<=n;i++) a[i]=read();
    	for(re int x,y,i=1;i<n;i++) x=read(),y=read(),add(x,y),add(y,x);
    	deep[ro]=1,dfs(ro);mx[0]=inf;
    	for(re int i=1;i<=n;i++) rt[i]=change(rt[i],1,md,deep[i],a[i]);
    	Dfs(ro);
    	int x,y,Q=read(),lst=0;
    	while(Q--) {
    		x=read(),y=read();
    		x+=lst;x%=n,x++;y+=lst;y%=n;
    		lst=query(rt[x],deep[x],deep[x]+y,1,md);
    		printf("%d
    ",lst);
    	}
    	return 0;
    }
    
    

    或许我们还可以直接(dsu on tree),对(dsu)里的桶可持久化,这样就是空间时间都多一个(log)

    主席树的做法巧妙的一批,我们可以以深度为时间轴,以(dfs)序为下标来建树

    查询的时候直接查([1,dep_x+k])(dfn_x<=dfn<=dfn_x+sum_x-1),由于(dfn)的限制,所以这样的点只会存在于(x)的子树里

  • 相关阅读:
    linux解压缩各种命令
    memset
    STRUCT_OFFSET( s, m )宏
    请问这个宏是什么意思 #define NOTUSED(v) ((void) v)?
    typedef特殊用法:typedef void* (*fun)(void*)
    localtime、localtime_s、localtime_r的使用
    Git使用(一)
    【转】linux gcc _attribute__((weak)) 简介及作用
    我的技术博客
    .net 4.0(2.0)“检测到有潜在危险的 Request.Form 值”的解决方法
  • 原文地址:https://www.cnblogs.com/asuldb/p/10539111.html
Copyright © 2020-2023  润新知