首页 > 代码库 > BZOJ 4530 LCT/线段树合并
BZOJ 4530 LCT/线段树合并
//By SiriusRen#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N=200050;int n,q,cnt,dfn[N],last[N],tree[N*16],lson[N*16],rson[N*16];int first[N],next[N],v[N],w[N],tot,root[N],fa[N],deep[N],f[N];struct Node{int xx,yy;char op[2];}node[N];void dfs(int x){ dfn[x]=++cnt; for(int i=first[x];~i;i=next[i]) if(v[i]!=fa[x])deep[v[i]]=deep[x]+1,fa[v[i]]=x,dfs(v[i]); last[x]=cnt;}void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;}void Add(int x,int y){add(x,y),add(y,x);}void insert(int l,int r,int &pos,int num,int wei){ if(!pos)pos=++cnt; if(l==r){tree[pos]=wei;return;} int mid=(l+r)>>1; if(mid<num)insert(mid+1,r,rson[pos],num,wei); else insert(l,mid,lson[pos],num,wei); tree[pos]=tree[lson[pos]]+tree[rson[pos]];}int query(int l,int r,int pos,int L,int R){ if(!pos)return 0; if(l>=L&&r<=R)return tree[pos]; int mid=(l+r)>>1; if(mid<L)return query(mid+1,r,rson[pos],L,R); else if(mid>=R)return query(l,mid,lson[pos],L,R); else return query(l,mid,lson[pos],L,R)+query(mid+1,r,rson[pos],L,R);}void merge(int pos1,int &pos2){ if(!pos2)pos2=++cnt; tree[pos2]+=tree[pos1];// printf("pos1=%d pos2=%d lson[pos1]=%d rson[pos1]=%d tree[pos]=%d\n",pos1,pos2,lson[pos1],rson[pos1],tree[pos2]); if(lson[pos1])merge(lson[pos1],lson[pos2]); if(rson[pos1])merge(rson[pos1],rson[pos2]);}int find(int x){return x==f[x]?x:f[x]=find(f[x]);}void dfs2(int x){ if(lson[x])dfs2(lson[x]); if(rson[x])dfs2(rson[x]);}int main(){ memset(first,-1,sizeof(first)); scanf("%d%d",&n,&q),getchar(); for(int i=1;i<=q;i++){ scanf("%s%d%d",node[i].op,&node[i].xx,&node[i].yy); if(node[i].op[0]==‘A‘)Add(node[i].xx,node[i].yy); } for(int i=1;i<=n;i++)if(!fa[i])dfs(i); cnt=0; for(int i=1;i<=n;i++)insert(1,n,root[i],dfn[i],1),f[i]=i; for(int i=1;i<=q;i++){ if(node[i].op[0]==‘A‘){ int fx=find(node[i].xx),fy=find(node[i].yy); if(fx!=fy)merge(root[fx],root[fy]),f[fx]=fy; } else{ if(deep[node[i].xx]>deep[node[i].yy])swap(node[i].xx,node[i].yy); int fy=find(node[i].yy); long long temp=query(1,n,root[fy],dfn[node[i].yy],last[node[i].yy]); printf("%lld\n",(tree[root[fy]]-temp)*temp); } }}
//By SiriusRen#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N=100050;int n,m,xx,yy,fa[N],ch[N][2],rev[N],size[N],Size[N],q[N],top;char op[10];bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}void push_up(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1+Size[x];}void push_down(int x){if(rev[x])rev[ch[x][0]]^=1,rev[ch[x][1]]^=1,swap(ch[x][0],ch[x][1]),rev[x]=0;}void rotate(int p){ int q=fa[p],y=fa[q],x=(ch[q][1]==p); ch[q][x]=ch[p][!x],fa[ch[q][x]]=q; ch[p][!x]=q,fa[p]=y; if(!isroot(q)){ if(ch[y][1]==q)ch[y][1]=p; if(ch[y][0]==q)ch[y][0]=p; }fa[q]=p,push_up(q);}void splay(int x){ q[++top]=x; for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i]; while(top)push_down(q[top]),top--; for(int y=fa[x];!isroot(x);rotate(x),y=fa[x])if(!isroot(y)){ if((ch[fa[y]][0]==y)^(ch[y][0]==x))rotate(x); else rotate(y); }push_up(x);}void access(int x){for(int t=0;x;t=x,x=fa[x])splay(x),Size[x]+=size[ch[x][1]]-size[t],ch[x][1]=t,push_up(x);}void makeroot(int x){access(x),splay(x),rev[x]^=1;}void link(int x,int y){makeroot(x),makeroot(y),fa[x]=y,Size[y]+=size[x],push_up(y);}void split(int x,int y){makeroot(x),access(y),splay(x);}int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)size[i]=1; while(m--){ scanf("%s%d%d",op,&xx,&yy); if(op[0]==‘A‘)link(xx,yy); else split(xx,yy),printf("%lld\n",1ll*(Size[yy]+1)*(size[xx]-Size[yy]-1)); }}
BZOJ 4530 LCT/线段树合并
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。