zoukankan      html  css  js  c++  java
  • HDU-6858 Discovery of Cycles (LCT,双指针,ST表)

    HDU-6858 Discovery of Cycles (LCT,双指针,ST表)

    Problem Description

    In response to the 8202 Olympics, Quber City, which was the host of the competition, is planning to build a magnificent stadium. The stadium is nowhere close to traditional stadiums that are typically embedded with a cyclic running trail. According to the plan, there are n service spots in the stadium, and m undirected running trails connecting them. Such adventurous design has brought worldwide attention to the stadium, but also comes with a huge cost.

    Therefore the designers are working to simplify the design to cut down the cost. They discovered that the easiest way to do this is to sort the m running trails in some particular order, and keep only some consecutive trails in the list. Since only part of the trails will be built, fund will be saved and everyone will be happy --- perhaps except those long-distance runners who needs a cyclic trail for the competition. A cyclic trail is a trail that starts at some service spot, passes through some distinct spots, before getting back to where it starts. All the running trails that have been used are required to be distinct. (This is by definition a simple cycle if you are familiar with terms in graph theory.)

    Your task is to write a program that can quickly check, whether one can find at least one simple cycle, given that the stadium is built with some particular running trails selected consecutively from the trail list.

    思路:

    双指针维护出(R_i)代表以第(mathit i) 个边开始加边,第一个会产生环的位置。

    需要用LCT的加边,删边,查询连通性这三个功能。

    然后对于(mathit R) 数组简历(ST) 表,那么对于每一个询问,我们只需要用(ST)表询问([l,r])区间最小值,然后将其与(mathit r) 比较下大小关系即可。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <bits/stdc++.h>
    #define ALL(x) (x).begin(), (x).end()
    #define sz(a) int(a.size())
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define chu(x)  if(DEBUG_Switch) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    #define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
    #define du2(a,b) scanf("%d %d",&(a),&(b))
    #define du1(a) scanf("%d",&(a));
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) { if (a == 0ll) {return 0ll;} a %= MOD; ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
    ll poww(ll a, ll b) { if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a ;} a = a * a ; b >>= 1;} return ans;}
    void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    inline long long readll() {long long tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
    inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
    void pvarr_int(int *arr, int n, int strat = 1) {if (strat == 0) {n--;} repd(i, strat, n) {printf("%d%c", arr[i], i == n ? '
    ' : ' ');}}
    void pvarr_LL(ll *arr, int n, int strat = 1) {if (strat == 0) {n--;} repd(i, strat, n) {printf("%lld%c", arr[i], i == n ? '
    ' : ' ');}}
    const int maxn = 1000010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    const int N = 300000 + 10;
    
    struct node {
        int ch[2], p;
        int revFlag;
    } nod[N];
    void revInterval(int x) {
        nod[x].revFlag ^= 1;
        swap(nod[x].ch[0], nod[x].ch[1]);
    }
    
    void pushdown(int x) {
        if (nod[x].revFlag) {
            if (nod[x].ch[0]) revInterval(nod[x].ch[0]);
            if (nod[x].ch[1]) revInterval(nod[x].ch[1]);
            nod[x].revFlag = 0;
        }
    }
    int type(int x) {
        if (nod[nod[x].p].ch[0] == x) return 0;
        if (nod[nod[x].p].ch[1] == x) return 1;
        return -1;
    }
    void rotate(int x) {
        int y = nod[x].p, z = nod[y].p, typo = type(x);
        if (type(y) != -1) {
            nod[z].ch[type(y)] = x;
        }
        nod[x].p = z;
        nod[y].ch[typo] = nod[x].ch[typo ^ 1], nod[nod[x].ch[typo ^ 1]].p = y;
        nod[x].ch[typo ^ 1] = y; nod[y].p = x;
    }
    void down(int x) {
        if (type(x) != -1) down(nod[x].p);
        pushdown(x);
    }
    void splay(int x) {
        down(x);
        for (; type(x) != -1 ; rotate(x)) {
            if (type(nod[x].p) != -1) {
                if (type(nod[x].p) == type(x))
                    rotate(nod[x].p);
                else
                    rotate(x);
            }
        }
    }
    void access(int x) {
        int y = 0;
        while (x) {
            splay(x);
            nod[x].ch[1] = y;
            y = x, x = nod[x].p;
        }
    }
    void makeroot(int x) {
        access(x);
        splay(x);
        revInterval(x);
    }
    int findroot(int x) {
        access(x);
        splay(x);
        while (nod[x].ch[0]) pushdown(x), x = nod[x].ch[0];
        return x;
    }
    void link(int x, int y) {
        makeroot(x); nod[x].p = y;
    }
    void split(int x, int y) {
        makeroot(x);
        access(y);
        splay(y);
    }
    void cut(int x, int y) {
        makeroot(x);
        if (findroot(y) != x || nod[x].p != y || nod[x].ch[1]) return ;
        nod[x].p = nod[y].ch[0] = 0;
    }
    void init(int n)
    {
        repd(i, 1, n)
        {
            nod[i].p = 0;
            nod[i].ch[0] = nod[i].ch[1] = 0;
        }
    }
    int n, q, op, x, y, m;
    pii e[maxn];
    int r[maxn];
    int st1[maxn][25];//st表
    int st2[maxn][25];//st表
    
    void init_st(int n)
    {
        for (int i = 0; i < n; i++)
        {
            st2[i][0] = r[i + 1];
        }
        for (int i = 1; (1 << i) <= n; i++)
        {
            for (int j = 0; j + (1 << i) - 1 < n; j++)
            {
                st2[j][i] = min(st2[j][i - 1], st2[j + (1 << (i - 1))][i - 1]);
            }
        }
    }
    inline int queryemin(int l, int r)
    {
        l--;
        r--;
        int k = (int)(log((double)(r - l + 1)) / log(2.0));
        return min(st2[l][k], st2[r - (1 << k) + 1][k]);
    }
    int main()
    {
        int t;
        t = readint();
        while (t--)
        {
            n = readint(); m = readint(); q = readint();
            repd(i, 1, m)
            {
                e[i].fi = readint();
                e[i].se = readint();
            }
            int id = 1;
            repd(i, 1, m)
            {
                r[i] = m + 1;
                while (id <= m)
                {
                    x = e[id].fi; y = e[id].se;
                    if (findroot(x) == findroot(y))
                    {
                        r[i] = id;
                        break;
                    } else {
                        link(x, y);
                        id++;
                    }
                }
                x = e[i].fi; y = e[i].se;
                cut(x, y);
            }
            init_st(m);
            int lastans = 0;
            while (q--)
            {
                int l = readint(); int r = readint();
                int k1 = (l ^ lastans) % m + 1;
                int k2 = (r ^ lastans) % m + 1;
                l = min(k1, k2);
                r = max(k1, k2);
                int res = queryemin(l, r);
                if (res <= r)
                {
                    lastans = 1;
                    printf("Yes
    ");
                } else
                {
                    lastans = 0;
                    printf("No
    ");
                }
            }
            init(n);
        }
        return 0;
    }
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    利用别名切换索引流程Elasticsearch 7.7
    关于误删除elasticSearch 索引,怎么能快速找回?
    总结traefik 在k8s 环境中的配置文件
    ES ElasticSearch 7.x 下动态扩大索引的shard数量
    Java框架Spring Boot & 服务治理框架Dubbo & 应用容器引擎Docker 实现微服务发布
    谈一下Docker与Kubernetes集群的日志和日志管理-转载
    Elasticsearch优化 & filebeat配置文件优化 & logstash格式配置 & grok实践
    Nginx错误日志(error_log)配置及信息详解
    赵总的运维体系专栏学习的总结
    APP或者前端通过识别用户代理详细信息和浏览器数据进行安全防御
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/13525784.html
Copyright © 2011-2022 走看看