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
    */
  • 相关阅读:
    031:verbatim 标签
    030:spaceless和autoescape 标签
    WinForm webbrowser控件的使用
    c# WebBrowser开发参考资料--杂七杂八
    C# Winform WebBrowser控件
    使用webBrowser进行C#和JS通讯
    webBrowser 应用编程函数总结
    C#网页采集数据的几种方式(WebClient、WebBrowser和HttpWebRequest/HttpWebResponse)
    利用WebBrowser控件实现百度自动搜索
    c#winform使用WebBrowser 大全
  • 原文地址:https://www.cnblogs.com/mowanying/p/11402204.html
Copyright © 2011-2022 走看看