zoukankan      html  css  js  c++  java
  • 暑假考试题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
    "),fl=0;
                else printf("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
    */
  • 相关阅读:
    为什么要学习Linux
    测试开发技术:DOM中 innerHTML、innerText、outerHTML、outerText的区别
    web service 组件
    老李分享:webservice是什么?
    hibernate 和 mybatis 的区别
    mybatis 缓存
    过滤器和拦截器
    Spring 注解
    Spring 全局异常处理
    mybatis Mapper XML 映射文件
  • 原文地址:https://www.cnblogs.com/mowanying/p/11402204.html
Copyright © 2011-2022 走看看