• BZOJ 3123 【SDOI2013】 森林


    题目链接:森林

      这道题想法很显然。既然只有加边而没有删边,那么每次启发式合并就可以了。查询路径(k)小似乎需要主席树,那么把主席树和倍增表一起暴力重构就好了。

      然后发现这样的空间复杂度是(O(nlog^2n))的。感觉非常不靠谱,于是滚去写了个节点回收站……然后发现主席树节点回收的话每个节点会被(dfs)到多次,还需要一些特判……

      然后就是一直(RE)……由于题目是强制在线的那么就应该是(Wa)了。但是对拍了(6W)组数据没出错我还能说什么呢……

      最后突然发现,我的倍增表在合并的时候好像没有清空……本来以为这样不会出问题,但是由于我的倍增的一些写法,就跳到了一些奇怪的节点上去……以后还是不那么写了,老老实实从上界开始(for)吧

      下面贴代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    #define maxn 80010
    #define MAXN 1500010
    
    using namespace std;
    typedef long long llg;
    
    int n,m,T,d[maxn],ld,rt[maxn],a[maxn],qz,lans;
    int head[maxn],next[maxn<<1],to[maxn<<1],tt;
    int sumv[MAXN],le[MAXN],ri[MAXN],q[MAXN],lq,rq,L;
    int f[maxn][17],dep[maxn],fa[maxn],siz[maxn];
    bool isin[MAXN];
    
    int getint(){
    	int w=0;bool q=0;
    	char c=getchar();
    	while((c>'9'||c<'0')&&c!='-') c=getchar();
    	if(c=='-') c=getchar(),q=1;
    	while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
    	return q?-w:w;
    }
    
    int find(int x){return fa[fa[x]]==fa[x]?fa[x]:fa[x]=find(fa[x]);}
    void qpush(int x){if(isin[x]) return; isin[x]=1;q[rq++]=x,rq%=MAXN;}
    int qtop(){
    	if(lq==rq) return ++qz;
    	int now=q[lq++]; lq%=MAXN;
    	isin[now]=0; return now;
    }
    
    void link(int x,int y){
    	to[++tt]=y;next[tt]=head[x];head[x]=tt;
    	to[++tt]=x;next[tt]=head[y];head[y]=tt;
    }
    
    int build(int u,int l,int r){
    	int now=qtop(),mid=(l+r)>>1;
    	le[now]=le[u]; ri[now]=ri[u];
    	sumv[now]=sumv[u]+1;
    	if(l!=r){
    		if(L<=mid) le[now]=build(le[u],l,mid);
    		else ri[now]=build(ri[u],mid+1,r);
    	}
    	return now;
    }
    
    void dfs(int u,int fr){
    	dep[u]=dep[fr]+1; f[u][0]=fr;
    	if(!fa[u]) fa[u]=(fr?find(fr):u); siz[find(u)]++;
    	L=a[u],rt[u]=build(rt[fr],1,ld);
    	for(int i=1;i<17;i++)
    		f[u][i]=f[f[u][i-1]][i-1];
    	for(int i=head[u];i;i=next[i])
    		if(to[i]!=fr) dfs(to[i],u);
    }
    
    void del(int u){if(!u || isin[u])return;qpush(u);del(le[u]);del(ri[u]);le[u]=ri[u]=0;}
    void shan(int u,int fr){
    	del(rt[u]);
    	for(int i=head[u];i;i=next[i])
    		if(to[i]!=fr) shan(to[i],u);
    }
    
    int lca(int u,int v){
    	if(dep[u]<dep[v]) swap(u,v);
    	for(int i=16;i>=0;i--)
    		if(dep[f[u][i]]>=dep[v])
    			u=f[u][i];
    	if(u==v) return u;
    	for(int i=16;i>=0;i--)
    		if(f[u][i]!=f[v][i])
    			u=f[u][i],v=f[v][i];
    	return f[u][0];
    }
    
    void merge(int x,int y){
    	int a=find(x),b=find(y);
    	if(siz[a]>siz[b]) swap(x,y),swap(a,b);
    	fa[a]=b; siz[b]+=siz[a];
    	shan(a,0); link(x,y); dfs(x,y);
    }
    
    int query(int x,int y,int k){
    	int p=lca(x,y),l=1,r=ld,mid,now,g;
    	x=rt[x]; y=rt[y]; g=rt[p];
    	while(l!=r){
    		mid=(l+r)>>1; now=(a[p]>=l && a[p]<=mid);
    		now+=sumv[le[x]]+sumv[le[y]]-(sumv[le[g]]<<1);
    		if(k<=now) r=mid,x=le[x],y=le[y],g=le[g];
    		else k-=now,l=mid+1,x=ri[x],y=ri[y],g=ri[g];
    	}
    	return l;
    }
    
    int main(){
    	File("a");
    	getint();
    	n=getint(); m=getint(); T=getint();
    	for(int i=1;i<=n;i++) d[++ld]=a[i]=getint();
    	sort(d+1,d+ld+1); ld=unique(d+1,d+ld+1)-d-1;
    	for(int i=1;i<=n;i++) a[i]=lower_bound(d+1,d+ld+1,a[i])-d;
    	while(m--) link(getint(),getint());
    	for(int i=1;i<=n;i++) if(!dep[i]) dfs(i,0);
    	while(T--){
    		char c=getchar(); int x,y;
    		while(c!='Q' && c!='L') c=getchar();
    		x=getint()^lans,y=getint()^lans;
    		if(c=='L') merge(x,y);
    		else printf("%d
    ",lans=d[query(x,y,getint()^lans)]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Codeforces 689A Mike and Cellphone
    栈的一些基本操作
    Intersecting Lines POJ 1269
    Segments POJ 3304 直线与线段是否相交
    Toy Storage POJ 2398
    CF471D MUH and Cube Walls
    P 3396 哈希冲突 根号分治
    P1445 [Violet]樱花
    P6810 「MCOI-02」Convex Hull 凸包
    P3455 [POI2007]ZAP-Queries
  • 原文地址:https://www.cnblogs.com/lcf-2000/p/6504753.html
Copyright © 2020-2023  润新知