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('\n')
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('\n');
    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('\n');
    }
    return 0;
}
View Code

 

posted @ 2019-07-21 19:08  yccdu  阅读(170)  评论(0编辑  收藏  举报