mxqz 可持久化并查集, 只有 12pts
查看原帖
mxqz 可持久化并查集, 只有 12pts
317805
BootsH楼主2022/2/13 19:49
#include <iostream>
#include <streambuf>
#include <fstream>
#include <cstring>
#include <algorithm>

namespace AKA
{
    #if __cplusplus >= 201103L
        using uint = unsigned int;
        using ll = long long;
        using ull = unsigned long long;
        using llrg = __int128_t;
        using ullrg = __uint128_t;
        using dbl = double;
        using ldbl = long double;
    #else
        typedef unsigned int uint;
        typedef long long ll;
        typedef unsigned long long ull;
        typedef __int128_t llrg;
        typedef __uint128_t ullrg;
        typedef double dbl;
        typedef long double ldbl;
    #endif    
} // namespace AKA


namespace IO
{
    using namespace AKA;
    std::streambuf* inbuf, *outbuf;
    char ibuf[1 << 23 | 1], *i1 = ibuf, *i2 = ibuf;
    char outstk[105];
    int top = 0;
    inline char gc() { return (i1 == i2 && (i2 = (i1 = ibuf) + inbuf->sgetn(ibuf, 1 << 23), i1 == i2) ? EOF : *i1++); }
    inline void pc(char x) { outbuf->sputc(x); }
    inline int iget() { int x = 0; bool f = false; char c = gc(); while (c < '0' || c > '9') { f |= c == '-'; c = gc(); } while (c >= '0' && c <= '9') { x = (x << 3) + (x << 1) + (c ^ 48); c = gc(); } return f ? -x : x; }
    inline void ipr(int x) { if (x == 0) { pc('0'); return ; } if (x < 0) { pc('-'); x = -x; } top = 0; while (x) { outstk[top++] = x % 10 + 48; x /= 10; } while (top--) { pc(outstk[top]); } }
    inline void iwsp(int x) { ipr(x); pc(' '); }
    inline void iwln(int x) { ipr(x); pc('\n'); }
    inline ll llget() { ll x = 0; bool f = false; char c = gc(); while (c < '0' || c > '9') { f |= c == '-'; c = gc(); } while (c >= '0' && c <= '9') { x = (x << 3) + (x << 1) + (c ^ 48); c = gc(); } return f ? -x : x; }
    inline void llpr(ll x) { if (x == 0) { pc('0'); return ; } if (x < 0) { pc('-'); x = -x; } top = 0; while (x) { outstk[top++] = x % 10 + 48; x /= 10; } while (top--) { pc(outstk[top]); } }
    inline void llwsp(ll x) { llpr(x); pc(' '); }
    inline void llwln(ll x) { llpr(x); pc('\n'); }
    inline ull ullget() { ll x = 0; bool f = false; char c = gc(); while (c < '0' || c > '9') { f |= c == '-'; c = gc(); } while (c >= '0' && c <= '9') { x = (x << 3) + (x << 1) + (c ^ 48); c = gc(); } return f ? -x : x; }
    inline void ullpr(ull x) { if (x == 0) { pc('0'); return ; } if (x < 0) { pc('-'); x = -x; } top = 0; while (x) { outstk[top++] = x % 10 + 48; x /= 10; } while (top--) { pc(outstk[top]); } }
    inline void ullwsp(ull x) { ullpr(x); pc(' '); }
    inline void ullwln(ull x) { ullpr(x); pc('\n'); }
    inline void spr(const char* s) { char* t = const_cast<char*>(s); while (*t && (pc(*t++), true)) {} }
    inline void swsp(const char* s) { spr(s); pc(' '); }
    inline void swln(const char* s) { spr(s); pc('\n'); }
    template<typename _Tp> inline void iget(_Tp& x) { x = 0; bool f = false; char c = gc(); while (c < '0' || c > '9') { f |= c == '-'; c = gc(); } while (c >= '0' && c <= '9') { x = (x << 3) + (x << 1) + (c ^ 48); c = gc(); } f && (x = -x); }
    template<typename _Tp, typename ... Args> inline void iget(_Tp& x, Args& ... args) { iget(x), iget(args ...); }
    template<typename _Tp> inline void pr(_Tp x) { if (x == 0) { pc('0'); return ; } if (x < 0) { pc('-'); x = -x; } top = 0; while (x) { outstk[top++] = x % 10 + 48; x /= 10; } while (top--) { pc(outstk[top]); } }
    template<typename _Tp, typename ... Args> inline void pr(_Tp x, Args ... args) { pr(x), pr(args ...); }
    template<typename _Tp> inline void wsp(_Tp x) { pr(x), pc(' '); }
    template<typename _Tp, typename ... Args> inline void wsp(_Tp x, Args ... args) { wsp(x), wsp(args ...); }
} // namespace IO



namespace Solution
{
    #ifndef ONLINE_JUDGE
        std::ifstream cin; 
        std::ofstream cout;
    #else  
        using std::cin;
        using std::cout;
    #endif
    using namespace AKA;
    using IO::gc; using IO::pc; 
    using IO::iget; using IO::ipr; using IO::iwsp; using IO::iwln;
    using IO::llget; using IO::llpr; using IO::llwsp; using IO::llwln;
    using IO::ullget; using IO::ullwsp; using IO::ullwln;
    using IO::spr; using IO::swsp; using IO::swln;
    using IO::pr; using IO::wsp; 
    #define flp(name, lpst, lped) for (int name = lpst, name##end = lped; name <= name##end; ++name)
    #define plf(name, lpst, lped) for (int name = lpst, name##end = lped; name >= name##end; --name)


    constexpr int maxn = 2e5 + 5;

    template<int maxn>
    struct DSU
    {
        struct Node 
        {
            int ls, rs, l, r, ff, d;
        } tr[maxn * 30 + 5];
        int rt[maxn];
        inline int& ls(int i) { return tr[i].ls; }
        inline int& rs(int i) { return tr[i].rs; }
        inline int& ff(int i) { return tr[i].ff; }
        inline int& d(int i) { return tr[i].d; }
        int ncnt = 0;
        void build(int l, int r, int& rt)
        {
            rt = ++ncnt;
            tr[rt].l = l, tr[rt].r = r;
            if (l == r)
            {
                ff(rt) = l;
                return ;
            }
            int mid = l + ((r - l) >> 1);
            build(l, mid, ls(rt)), build(mid + 1, r, rs(rt));
        }  
        void upd(int pos, int rt)
        {
            if (tr[rt].l == tr[rt].r)
            {
                ++d(rt);
                return ;
            }
            if (pos <= tr[ls(rt)].r)
            {
                upd(pos, ls(rt));
            }
            else  
            {
                upd(pos, rs(rt));
            }
        }
        void mrg(int pos, int fa, int pre, int& rt)
        {
            rt = ++ncnt;
            tr[rt] = tr[pre];
            d(rt) = 0;
            if (tr[rt].l == tr[rt].r)
            {
                ff(rt) = fa;
                d(rt) = d(pre);
                return ;
            }
            if (pos <= tr[ls(rt)].r)
            {
                mrg(pos, fa, ls(pre), ls(rt));
            }
            else  
            {
                mrg(pos, fa, rs(pre), rs(fa));
            }
        }
        int qry(int pos, int rt)
        {
            if (tr[rt].l == tr[rt].r)
            {
                return rt;
            }
            if (pos <= tr[ls(rt)].r)
            {
                return qry(pos, ls(rt));
            }
            else  
            {
                return qry(pos, rs(rt));
            }
        }
        int getf(int pos, int rt)
        {
            int x = qry(pos, rt);
            if (ff(x) == pos)
            {
                return x;
            }
            return getf(ff(x), rt);
        }
    };

    DSU<maxn> dsu;


    void main(void)
    {
        std::ios::sync_with_stdio(false);
        #ifndef ONLINE_JUDGE
            cin.open("main.in"), cout.open("main.out");
            IO::inbuf = cin.rdbuf(); IO::outbuf = cout.rdbuf();
        #else
            #if __cplusplus >= 201103L
                cin.tie(nullptr); cout.tie(nullptr);
            #else
                cin.tie(NULL); cout.tie(NULL);
            #endif
            IO::inbuf = cin.rdbuf(); IO::outbuf = cout.rdbuf();
        #endif

        std::ofstream ferr("main.err.out");

        #define iwln(x) (ferr << (x) << std::endl)


        int n = iget(), General_Q = iget();
        dsu.build(1, n, dsu.rt[0]);
        // std::cerr << "build\n";
        flp (i, 1, General_Q)
        {
            std::cerr << i << "\n";
            int op = iget(), x = iget();
            if (op == 1)
            {
                int y = iget();
                dsu.rt[i] = dsu.rt[i - 1];
                int fx = dsu.getf(x, dsu.rt[i]), fy = dsu.getf(y, dsu.rt[i]);
                if (dsu.ff(fx) != dsu.ff(fy))
                {
                    if (dsu.d(fx) > dsu.d(fy))
                    {
                        std::swap(fx, fy);
                    }
                    dsu.mrg(dsu.ff(fx), dsu.ff(fy), dsu.rt[i - 1], dsu.rt[i]);
                    if (dsu.d(fx) == dsu.d(fy))
                    {
                        dsu.upd(dsu.ff(fy), dsu.rt[i]);
                    }
                }
            }
            else if (op == 2)
            {
                dsu.rt[i] = dsu.rt[x];
            }
            else if (op == 3)
            {
                int y = iget();
                dsu.rt[i] = dsu.rt[i - 1];
                int fx = dsu.getf(x, dsu.rt[i]), fy = dsu.getf(y, dsu.rt[i]);
                iwln(dsu.ff(fx) == ff(fy));
            }
        }


        #ifndef ONLINE_JUDGE
            cin.close(); cout.close();
        #endif
    }
} // namespace Solution

int main(void)
{
    Solution::main();
    return 0;
}
2022/2/13 19:49
加载中...