WA2,3,4,5,6 TLE8 求助聚聚们
查看原帖
WA2,3,4,5,6 TLE8 求助聚聚们
435689
sillage丶楼主2021/10/12 17:20

rt,可持久化数组部分应该是没问题的,大概率错在merge或者find,谢谢聚聚。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <numeric>
#include <algorithm>
#include <functional>
#include <map>
#include <queue>
#include <vector>
#include <utility>

#define ed end()
#define bg begin()
#define mp make_pair
#define pb push_back
#define all(x) x.bg, x.ed
#define newline puts("")
#define si(x) ((int)x.size())
#define rep(i, n) for(register int i = 1; i <= n; ++i)
#define rrep(i, n) for(register int i = 0; i < n; ++i)
#define srep(i, s, t) for(register int i = s; i <= t; ++i)
#define drep(i, s, t) for(register int i = t; i >= s; --i)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int MAX = 2e5 + 10;
const int INF = 0x3f3f3f3f;
const ll INF_ll = 1ll * INF * INF;
const int MOD = 1e9 + 7;
const double eps = 1e-7;

int n, m;

struct node
{
    int l, r, val;
} tr[MAX << 8];//此时的线段树维护了两个可持久化数组。

int rtf[MAX], rtd[MAX];//使用两个不同的数组来分别存父亲和深度树

int cnt;
int tot;//用来初始化并查集数组

inline int clone(int p)
{
    tr[++cnt] = tr[p];
    return cnt;
}

inline int r(){
    char c = getchar();int x = 0,fh = 0;
    while(c < '0' || c > '9'){fh |= c == '-';c = getchar();}
    while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
    return fh?-x:x;
}

//只有并查集数组要初始化为自身,树高数组一开始都为零。
int build(int p, int s, int e)
{
    p = ++cnt;
    if(s == e)
    {
        tr[p].val = ++tot;
        return cnt;
    }
    int mid = s + ((e - s) >> 1);
    tr[p].l = build(tr[p].l, s, mid);
    tr[p].r = build(tr[p].r, mid + 1, e);
    return p;
}

int modify(int p, int s, int e, int pos, int nval)
{
    p = clone(p);
    if(s == e)
    {
        tr[p].val = nval;
        return p;
    }
    int mid = s + ((e - s) >> 1);
    if(pos <= mid) tr[p].l = modify(tr[p].l, s, mid, pos, nval);
    else tr[p].r = modify(tr[p].r, mid + 1, e, pos, nval);
    return p;
}

int query(int p, int s, int e, int pos)
{
    if(s == e) return tr[p].val;
    int mid = s + ((e - s) >> 1);
    if(pos <= mid) return query(tr[p].l, s, mid, pos);
    else return query(tr[p].r, mid + 1, e, pos);
}

inline int find(int ver, int x)
{
    int fx = query(rtf[ver], 1, n, x);
    return (fx == x) ? x : find(ver, fx);
}

void merge(int ver, int x, int y)
{
    int fx = find(ver - 1, x);
    int fy = find(ver - 1, y);
    if(fx == fy)
    {
        rtf[ver] = rtf[ver - 1];
        rtd[ver] = rtd[ver - 1];
    }
    else
    {
        int depx = query(rtd[ver - 1], 1, n, x);
        int depy = query(rtd[ver - 1], 1, n, y);
        if(depx > depy)
        {
            rtf[ver] = modify(rtf[ver - 1], 1, n, y, x);
            rtd[ver] = rtd[ver - 1];
        }
        else if(depx < depy)
        {
            rtf[ver] = modify(rtf[ver - 1], 1, n, x, y);
            rtd[ver] = rtd[ver - 1];
        }
        else
        {
            rtf[ver] = modify(rtf[ver - 1], 1, n, x, y);
            rtd[ver] = modify(rtd[ver - 1], 1, n, y, depy + 1);
        }
    }
}

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("Slove.in","r", stdin);
        freopen("Slove.out","w", stdout);
    #endif
    n = r(), m = r();
    rtf[0] = build(0, 1, n);
    rep(i, m)
    {
        int op;
        op = r();
        if(1 == op)
        {
            int a, b;
            a = r(), b = r();
            merge(i, a, b);
            // int fa = find(i, a), fb = find(i, b);
            // printf("%c\n", (fa == fb) ? 'Y' : 'N');
        }
        else if(2 == op)
        {
            int k;
            k = r();
            rtf[i] = rtf[k];
            rtd[i] = rtd[k]; 
        }
        if(3 == op)
        {
            int a, b;
            a = r(), b = r();
            rtf[i] = rtf[i - 1];
            rtd[i] = rtd[i - 1];
            int fa = find(i, a), fb = find(i, b);
            // printf("f[%d] = %d f[%d] = %d\n", a, fa, b, fb);
            printf("%d\n", (fa == fb) ? 1 : 0);
        }
    }
    return 0;
}
2021/10/12 17:20
加载中...