• 7.19T3


    小 X 的图
    题目背景及题意
    小 X 有一张图,有 n 个点(从 0 开始编号),一开始图里并没有
    边,他有时候会向其中添加一条双向边(x 到 y)。小 X 会时不时想知
    道某两个点是否联通,如果连通并在 t 次加边操作之前不连通,他就
    会对自己加的边感到满意,否则他就会生气,并会错误地记录接下来
    添加的边,将 x 记录为(x+n-c)%n ,y 记录为(y+n-c)%n。直到
    他下一次询问为止。C 是一个小 X 随意定的值(一开始是 0),当然也
    会随他意愿修改。
    你的任务就是回答他的每一次询问
    输入格式
    第一行 n,m,表示点的个数和小 X 操作的总数
    接下来 m 行,每行先是一个字符
    “K”:接下来一个数字 c,表示小 X 新的 c 值
    “R”:接下来两个整数 u,v,表示连一条双向边
    “T”:接下来三个整数 u,v,t,表示询问 u 到 v 的连通性,t 的意
    义上文已经提到过了
    保证:无自环(但有重边
    输出格式
    对于每个询问输出一行“Y”代表小 X 满意,“N”代表小 X 生气
    样例数据 详见 sample 文件夹
     
    数据范围
    对于 30%的数据 n<=1000,m<=3000
    对于剩余数据:n , m<=300000
    对于所有数据:0<=t<=m(但有可能向前第 t 次加边不存在
    提示:做完这题你就 AK 了,是不是很开心呢
     
    sol:这大概就是一道可持久化并查集裸题。虽然300000两只log看上去有点不可过,但就是过了。。。
    #include <bits/stdc++.h>
    using namespace std;
    typedef int ll;
    inline ll read()
    {
        ll s=0; bool f=0; char ch=' ';
        while(!isdigit(ch)) {f|=(ch=='-'); ch=getchar();}
        while(isdigit(ch)) {s=(s<<3)+(s<<1)+(ch^48); ch=getchar();}
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0) {putchar('-'); x=-x;}
        if(x<10) {putchar(x+'0'); return;}
        write(x/10); putchar((x%10)+'0');
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) write(x),putchar('
    ')
    const int N=300005;
    inline void copy(int &x,int y,int l,int r);
    inline void Build(int &x,int l,int r);
    inline void Chag(int &x,int y,int l,int r,int Pos,int Val);
    inline int Que(int x,int l,int r,int Pos);
    int n,m,cnt=0,Now;
    int fa[N],sz[N];
    vector<int>Jh[N];
    int rt[N<<2];
    #define PB push_back
    struct Node
    {
        int ls,rs,id;
    }T[N*105];
    inline int gf(int x){return (x==fa[x])?(x):(fa[x]=gf(fa[x]));}
    inline void ubbon(int x,int y)
    {
        int i,xx=gf(x),yy=gf(y);
        if(xx==yy)
        {
    //        cout<<"@@@@@"<<x<<' '<<y<<endl;
            copy(rt[Now],rt[Now-1],1,n); return;
        }
        if(sz[xx]<sz[yy]) swap(xx,yy);
        fa[yy]=xx; sz[xx]+=sz[yy];
        int oo[2],t=0; copy(oo[t],rt[Now-1],1,n);
        for(i=0;i<Jh[yy].size();i++)
        {
            t^=1; oo[t]=0;
            Chag(oo[t],oo[t^1],1,n,Jh[yy][i],xx);
            Jh[xx].PB(Jh[yy][i]);
        }
        copy(rt[Now],oo[t],1,n);
        Jh[yy].clear();
    }
    inline void Build(int &x,int l,int r)
    {
        x=++cnt;
        if(l==r)
        {
            T[x].id=l; return;
        }
        int mid=(l+r)>>1;
        Build(T[x].ls,l,mid); Build(T[x].rs,mid+1,r);
    }
    inline void copy(int &x,int y,int l,int r)
    {
        x=y;
    }
    inline void Chag(int &x,int y,int l,int r,int Pos,int Val)
    {
        x=++cnt; T[x]=T[y];
        if(l==r)
        {
            T[x].id=Val; return;
        }
        int mid=(l+r)>>1;
        if(Pos<=mid) Chag(T[x].ls,T[y].ls,l,mid,Pos,Val);
        else Chag(T[x].rs,T[y].rs,mid+1,r,Pos,Val);
    }
    inline int Que(int x,int l,int r,int Pos)
    {
        if(l==r) return T[x].id;
        int mid=(l+r)>>1;
        if(Pos<=mid) return Que(T[x].ls,l,mid,Pos);
        else return Que(T[x].rs,mid+1,r,Pos);
    }
    int main()
    {
        freopen("history.in","r",stdin);
        freopen("history.out","w",stdout);
        int i,C=0,x,y,z,Last; char S[5];
        R(n); R(m);
        for(i=1;i<=n;i++) {fa[i]=i; sz[i]=1; Jh[i].PB(i);}
        Build(rt[Now=0],1,n);
    //    for(i=1;i<=n;i++) cout<<Que(rt[Now],1,n,i)<<' ';
    //    putchar('
    ');
        int Test=0;
        while(m--)
        {
            scanf("%s",S+1);
            switch (S[1])
            {
                case 'K':
                    R(C);
                    break;
                case 'R':
                    R(x); R(y);
                    x=(x+Last*C)%n; y=(y+Last*C)%n;
                    x++; y++;
    //                cout<<"RRR"<<' '<<x<<' '<<y<<endl;
                    Now++;
                    ubbon(x,y);
                    break;
                case 'T':
                    R(x); R(y); R(z);
                    x++; y++;
                    if(x==y) {puts("N"); Last=1; break;}
                    int xx=gf(x),yy=gf(y);
                    if(xx==yy)
                    {
                        if(Now<z) puts("Y"),Last=0;
                        else
                        {
                            int c1=Que(rt[Now-z],1,n,x),c2=Que(rt[Now-z],1,n,y);
                            if(c1==c2) puts("N"),Last=1;
                            else puts("Y"),Last=0;
                        }
                    }
                    else puts("N"),Last=1;
    //                if(++Test==185) return 0;
                    break;
            }
    //        for(i=1;i<=n;i++) cout<<Que(rt[Now],1,n,i)<<' ';
    //        putchar('
    ');
        }
        return 0;
    }
    View Code
  • 相关阅读:
    无法重用Linq2Entity Query
    The Joel Test
    MSBuilder directly instead of default VSComplie with keyborad shotcut 原创
    客户端缓存(Client Cache)
    关于代码重构和UT的一些想法,求砖头
    ExtJS2.0实用简明教程 应用ExtJS
    Perl information,doc,module document and FAQ.
    使用 ConTest 进行多线程单元测试 为什么并行测试很困难以及如何使用 ConTest 辅助测试
    史上最简单的Hibernate入门简介
    汽车常识全面介绍 传动系统
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/11222271.html
Copyright © 2020-2023  润新知