zoukankan      html  css  js  c++  java
  • 【HDU-6223/2017ICPC沈阳G】Infinite Fraction Path(后缀数组+超级快读)

    题目链接:https://vjudge.net/problem/HDU-6223

    题目大意

    给定一张图有 (N) 个点,编号为 (0,...,N-1),每个点都从自身有一条到点 (i^{2}+1) 的边(有向),点上有点权,点权为 (0,...,9),走过一条路径最终获得的字符串为点权字符串拼起来。问走 (N) 步,能得到的最大字符串为多少。

    思路

    后缀数组中有一个技巧是倍增进行比较,从而得到 (O(n log n)) 的复杂度,那么只要将后缀数组中的 (+w) 替换为 (to[u][w]) 进行倍增即可。

    但是这样做会疯狂TLE,考虑到读入可能量很大,加上超级快读就过了。

    AC代码

    #include <bits/stdc++.h>
    
    #define FI(n) FastIO::read(n)
    #define FO(n) FastIO::write(n)
    #define Flush FastIO::Fflush()
    typedef long long ll;
    using namespace std;
    
    namespace FastIO {  // 超级快读
        const int SIZE = 1 << 16;
        char buf[SIZE], obuf[SIZE], str[60];
        int bi = SIZE, bn = SIZE, opt;
        double D[] = {0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, 0.00000001, 0.000000001, 0.0000000001};
    
        int read(char *s) {
            while (bn) {
                for (; bi < bn && buf[bi] <= ' '; bi++);
                if (bi < bn) break;
                bn = fread(buf, 1, SIZE, stdin);
                bi = 0;
            }
            int sn = 0;
            while (bn) {
                for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
                if (bi < bn) break;
                bn = fread(buf, 1, SIZE, stdin);
                bi = 0;
            }
            s[sn] = 0;
            return sn;
        }
    
        bool read(int &x) {
            int n = read(str), bf = 0;
            if (!n) return 0;
            int i = 0;
            if (str[i] == '-') bf = 1, i++; else if (str[i] == '+') i++;
            for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
            if (bf) x = -x;
            return 1;
        }
    
        bool read(long long &x) {
            int n = read(str), bf;
            if (!n) return 0;
            int i = 0;
            if (str[i] == '-') bf = -1, i++; else bf = 1;
            for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
            if (bf < 0) x = -x;
            return 1;
        }
    
        void write(int x) {
            if (x == 0) obuf[opt++] = '0';
            else {
                if (x < 0) obuf[opt++] = '-', x = -x;
                int sn = 0;
                while (x) str[sn++] = x % 10 + '0', x /= 10;
                for (int i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
            }
            if (opt >= (SIZE >> 1)) {
                fwrite(obuf, 1, opt, stdout);
                opt = 0;
            }
        }
    
        void write(long long x) {
            if (x == 0) obuf[opt++] = '0';
            else {
                if (x < 0) obuf[opt++] = '-', x = -x;
                int sn = 0;
                while (x) str[sn++] = x % 10 + '0', x /= 10;
                for (int i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
            }
            if (opt >= (SIZE >> 1)) {
                fwrite(obuf, 1, opt, stdout);
                opt = 0;
            }
        }
    
        void write(unsigned long long x) {
            if (x == 0) obuf[opt++] = '0';
            else {
                int sn = 0;
                while (x) str[sn++] = x % 10 + '0', x /= 10;
                for (int i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
            }
            if (opt >= (SIZE >> 1)) {
                fwrite(obuf, 1, opt, stdout);
                opt = 0;
            }
        }
    
        void write(char x) {
            obuf[opt++] = x;
            if (opt >= (SIZE >> 1)) {
                fwrite(obuf, 1, opt, stdout);
                opt = 0;
            }
        }
    
        void Fflush() {
            if (opt) fwrite(obuf, 1, opt, stdout);
            opt = 0;
        }
    };
    
    const int MAXN = 150005;
    
    
    int to[MAXN][22];
    
    int sa[MAXN], rk[MAXN << 1], oldrk[MAXN << 1], id[MAXN], cnt[MAXN];
    
    void run(int s[], int n) {
        int m = 10;
        for (int i = 0; i <= m; i++) cnt[i] = 0;
        for (int i = 1; i <= n; i++) ++cnt[rk[i] = s[i]];
        for (int i = 1; i <= m; i++) cnt[i] += cnt[i - 1];
        for (int i = n; i >= 1; i--) sa[cnt[rk[i]]--] = i;
    
        int n2 = (n << 1);
        for (int i = n + 1; i <= n2; i++) oldrk[i] = rk[i] = 0;
    
        for (int w = 0; (1 << w) <= n; w++) {
            for (int i = 0; i <= m; i++) cnt[i] = 0;
            for (int i = 1; i <= n; i++) id[i] = sa[i];
            for (int i = 1; i <= n; i++) ++cnt[rk[to[id[i]][w]]];
            for (int i = 1; i <= m; i++) cnt[i] += cnt[i - 1];
            for (int i = n; i >= 1; i--) sa[cnt[rk[to[id[i]][w]]]--] = id[i];
    
            for (int i = 0; i <= m; i++) cnt[i] = 0;
            for (int i = 1; i <= n; i++) id[i] = sa[i];
            for (int i = 1; i <= n; i++) ++cnt[rk[id[i]]];
            for (int i = 1; i <= m; i++) cnt[i] += cnt[i - 1];
            for (int i = n; i >= 1; i--) sa[cnt[rk[id[i]]]--] = id[i];
            for (int i = 0; i <= n; i++) oldrk[i] = rk[i];
            int p = 0;
            for (int i = 1; i <= n; i++) {
                if (oldrk[sa[i]] == oldrk[sa[i - 1]] && oldrk[to[sa[i]][w]] == oldrk[to[sa[i - 1]][w]]) rk[sa[i]] = p;
                else rk[sa[i]] = ++p;
            }
            m = p;
            if (p >= n) break;
        }
    }
    
    char str[MAXN];
    int a[MAXN];
    
    int main() {
        int T, kass = 1;
        FI(T);//scanf("%d", &T);
        while (T--) {
            int n;
            FI(n);// scanf("%d", &n);
            FI(str + 1);//scanf("%s", str + 1);
            for (int i = 1; i <= n; i++) {
                a[i] = str[i] - '0' + 1; // 1,2,..10
                to[i][0] = ((ll) (i - 1) * (i - 1) + 1) % n + 1;
            }
    
            for (int i = 1; i <= 20; i++) {
                for (int j = 1; j <= n; j++)
                    to[j][i] = to[to[j][i - 1]][i - 1];
            }
            run(a, n);
    
            FO('C'), FO('a'), FO('s'), FO('e'), FO(' '), FO('#'), FO(kass++), FO(':'), FO(
                    ' ');// printf("Case #%d: ", kass++);
            int tmp = sa[n];
            for (int i = 1; i <= n; i++) {
                FO(a[tmp] - 1);//printf("%d", a[tmp] - 1);
                tmp = to[tmp][0];
            }
            FO('
    ');// printf("
    ");
        }
        Flush;
    }
    

    附上一组测试数据:

    2
    10
    0418499462
    15
    351222822042405
    

    正解为:

    Case #1: 9940419940
    Case #2: 822212212212212
    
  • 相关阅读:
    最小费用流(km的另一种使用思路)
    最小费用流(km的另一种使用思路)
    Python 字符串格式化
    Python字符串运算符
    Python 字符串连接
    Python 访问字符串中的值
    虚拟纹理与几何图像技术
    深度学习与传统图像识别
    ASML光刻机PK 原子弹,难度?
    L4自动驾驶技术
  • 原文地址:https://www.cnblogs.com/tudouuuuu/p/14091196.html
Copyright © 2011-2022 走看看