暑假考试题2:History(可持久化并查集)

题目:

分析:

求历史两个点之间是否连通->可持久化并查集。

注意:点的标号从0开始,主席树的范围应该是:0~n-1

#include<bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
#define N 9000005
int ndnum=0,lc[N],rc[N],fa[N],dep[N],ed[N],n,m;
void build(int s,int l,int r)
{
    if(l==r) { fa[s]=l; return ; }
    build(lc[s]=++ndnum,l,mid); build(rc[s]=++ndnum,mid+1,r);
}
void modify(int s,int l,int r,int pos)
{
    if(l==r) { dep[s]++; return ; }
    if(pos<=mid) modify(lc[s],l,mid,pos);
    else modify(rc[s],mid+1,r,pos);
}
int query(int s,int l,int r,int pos)
{
    if(l==r) return s;
    if(pos<=mid) return query(lc[s],l,mid,pos);
    else return query(rc[s],mid+1,r,pos);
}
void merge(int last,int &rt,int l,int r,int pos,int f)
{
    rt=++ndnum; lc[rt]=lc[last]; rc[rt]=rc[last];
    if(l==r) { fa[rt]=f; dep[rt]=dep[last]; return ; }
    if(pos<=mid) merge(lc[last],lc[rt],l,mid,pos,f);
    else merge(rc[last],rc[rt],mid+1,r,pos,f);
}
int get_fa(int s,int pos)
{
    int now=query(s,0,n-1,pos);
    if(fa[now]==pos) return now;
    return get_fa(s,fa[now]);
}
char op[5];
int main()
{
    freopen("history.in","r",stdin);
    freopen("history.out","w",stdout);
    int v,x,y,c=0,t,fl=0;
    scanf("%d%d",&n,&m);
    build(ed[0]=++ndnum,0,n-1);
    int i=0;
    while(m--){
        scanf("%s",op);
        if(op[0]=='K') scanf("%d",&v),c=v,fl=0;//注意题意:换国王之后就不生气了 
        if(op[0]=='R'){
            i++; ed[i]=ed[i-1];
            scanf("%d%d",&x,&y);
            if(fl) x=(x+c)%n,y=(y+c)%n;
            int f1=get_fa(ed[i],x),f2=get_fa(ed[i],y);
            if(fa[f1]==fa[f2]) continue;
            if(dep[f1]>dep[f2]) swap(f1,f2);
            merge(ed[i-1],ed[i],0,n-1,fa[f1],fa[f2]);
            if(dep[f1]==dep[f2]) modify(ed[i],0,n-1,fa[f2]);
        }
        if(op[0]=='T'){
            scanf("%d%d%d",&x,&y,&t);
            int f1=get_fa(ed[max(0,i-t)],x),f2=get_fa(ed[max(0,i-t)],y);
            int f3=get_fa(ed[i],x),f4=get_fa(ed[i],y);
            if(fa[f1]!=fa[f2]&&fa[f3]==fa[f4]) printf("Y\n"),fl=0;
            else printf("N\n"),fl=1;
        }
    }
    return 0;
}
/*
3 7
R 0 1
T 0 1 1
K 1
R 0 1
T 0 1 1
R 0 1
T 0 2 1
*/

猜你喜欢

转载自www.cnblogs.com/mowanying/p/11402204.html
今日推荐