zoukankan      html  css  js  c++  java
  • 【BZOJ1803】Query on a tree III(主席树SB题)

    点此看题面

    大致题意: 求子树第(k)大。

    (SB)

    显然求出原序列的(dfs)序列,然后子树就变成了一个区间。

    动态第(k)大可以用树套树(分块:?),静态第(k)大直接主席树就好了,显然是裸题。

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    #define LN 25
    #define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
    using namespace std;
    int n,a[N+5],g[N+5],ee,lnk[N+5],d,dI[N+5],dO[N+5],f[N+5];struct edge {int to,nxt;}e[N<<1];
    class FastIO
    {
    	private:
    		#define FS 100000
    		#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
    		#define pc(c) (C==E&&(clear(),0),*C++=c)
    		#define D isdigit(c=tc())
    		int T;char c,*A,*B,*C,*E,FI[FS],FO[FS],S[FS];
    	public:
    		I FastIO() {A=B=FI,C=FO,E=FO+FS;}
    		Tp I void read(Ty& x) {x=0;W(!D);W(x=(x<<3)+(x<<1)+(c&15),D);}
    		Tp I void writeln(Ty x) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);pc('
    ');}
    		I void clear() {fwrite(FO,1,C-FO,stdout),C=FO;}
    }F;
    class ChairmanTree
    {
    	private:
    		#define LT l,mid,O[x].S[0],O[y].S[0]
    		#define RT mid+1,r,O[x].S[1],O[y].S[1]
    		int Nt,Rt[N+5];struct node {int Sz,S[2];}O[N*LN+5];
    		I void Ins(CI p,CI l,CI r,int& x,CI y)//插入一个数
    		{
    			if(++(O[x=++Nt]=O[y]).Sz,l==r) return;int mid=l+r>>1;
    			p<=mid?Ins(p,LT):Ins(p,RT);
    		}
    		I int Qry(CI rk,CI l,CI r,CI x,CI y)//询问
    		{
    			if(l==r) return g[l];int mid=l+r>>1,t=O[O[y].S[0]].Sz-O[O[x].S[0]].Sz;
    			return rk<=t?Qry(rk,LT):Qry(rk-t,RT);
    		}
    	public:
    		I void Ins(CI v,CI x) {Ins(x,1,n,Rt[v],Rt[v-1]);}
    		I int Qry(CI x,CI y) {return Qry(y,1,n,Rt[dI[x]-1],Rt[dO[x]]);}
    }C;
    I void dfs(CI x)//求出dfs序列
    {
    	f[dI[x]=++d]=x;for(RI i=lnk[x];i;i=e[i].nxt) !dI[e[i].to]&&(dfs(e[i].to),0);dO[x]=d;
    }
    I bool cmp(CI x,CI y) {return a[x]<a[y];}
    int main()
    {
    	RI Qt,i,x,y;for(F.read(n),i=1;i<=n;++i) F.read(a[i]),g[i]=i;
    	for(sort(g+1,g+n+1,cmp),i=1;i<=n;++i) a[g[i]]=i;//离散化(因为保证数各不同)
    	for(i=1;i^n;++i) F.read(x),F.read(y),add(x,y),add(y,x);dfs(1);//连边dfs
    	for(i=1;i<=n;++i) C.Ins(i,a[f[i]]);//插入元素
    	F.read(Qt);W(Qt--) F.read(x),F.read(y),F.writeln(C.Qry(x,y));//处理询问
    	return F.clear(),0;
    }
    
  • 相关阅读:
    从Kratos设计看Go微服务工程实践
    京东到家安全测试实践
    浅谈 Protobuf 编码 原创 gsonli 腾讯技术工程 2021-07-14
    API Design Guide
    The power of two choices in randomized load balancing
    NGINX and the "Power of Two Choices" Load-Balancing Algorithm
    SRE 崩溃
    DDoS木马
    String.fromCharCode(88,83,83) 方法返回由指定的 UTF-16 代码单元序列创建的字符串
    汇编语言的AX,BX,CX,DX,分别表示什么
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ1803.html
Copyright © 2011-2022 走看看