zoukankan      html  css  js  c++  java
  • UVALive 4975 Casting Spells

    UVALive_4975

        可以先用Manacher算法预处理出每个字符i处的回文半径Ri,也就是最大的Ri使得i-Ri~i+Ri-1构成回文串。

        之后枚举每个字符i作为wwRwwR中后面这个的wwR的起始字符,然后在[i-Ri/2,i-1]的范围内找到最小的j使得j+Rj>=i,如果存在这样的j,那么就存在一个长度为4*(i-j)的wwRwwR式的回文串。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    #define INF 0x3f3f3f3f
    #define MAXD 300010
    int L, N, D, p[2 * MAXD], r[MAXD], tree[4 * MAXD];
    char str[MAXD], b[2 * MAXD];
    struct St
    {
        int id, v;
        St(){}
        St(int _id, int _v) : id(_id), v(_v){}
        bool operator < (const St &t) const
        {
            return v > t.v;
        }
    };
    void prep()
    {
        int i, id, max = 0;
        for(i = 0; str[i]; i ++) b[2 * i + 1] = '#', b[2 * i + 2] = str[i];
        L = i, N = 2 * i + 1;
        b[0] = '$', b[N] = b[N + 1] = '#';
        for(i = 1; i <= N; i ++)
        {
            p[i] = i < max ? std::min(max - i, p[2 * id - i]) : 1;
            while(b[i + p[i]] == b[i - p[i]]) ++ p[i];
            if(i + p[i] > max) max = i + p[i], id = i;
        }
        for(i = 0; i < L; i ++) r[i] = (p[2 * i + 1] - 1) / 2;
    }
    void init()
    {
        int i, j;
        scanf("%s", str);
        prep();
    }
    void update(int i)
    {
        for(; i ^ 1; i >>= 1) tree[i >> 1] = std::min(tree[i], tree[i ^ 1]);
    }
    int query(int x, int y)
    {
        int i = D + x - 1, j = D + y + 1, ans = INF;
        for(; i + 1 != j; i >>= 1, j >>= 1)
        {
            if(~i & 1) ans = std::min(ans, tree[i ^ 1]);
            if(j & 1) ans = std::min(ans, tree[j ^ 1]);
        }
        return ans;
    }
    void solve()
    {
        int i, j, ans = 0;
        for(D = 1; D < L + 2; D <<= 1);
        memset(tree, 0x3f, sizeof(tree[0]) * 2 * D);
        std::priority_queue <St> q;
        for(i = 0; i < L; i ++)
        {
            while(!q.empty())
            {
                St st = q.top();
                if(st.v >= i) break;
                q.pop(), tree[D + st.id] = INF, update(D + st.id);
            }
            q.push(St(i, i + r[i])), tree[D + i] = i, update(D + i);
            if(r[i] < 2) continue;
            j = query(i - r[i] / 2, i - 1);
            if(j != INF) ans = std::max(ans, 4 * (i - j));
        }
        printf("%d\n", ans);
    }
    int main()
    {
        int t;
        scanf("%d", &t);
        while(t --)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    仿QQ信息弹出
    天高云淡 leobbs皮肤
    http://www.xywq.com/files/ganzhi11.htm
    用Silverlight打造位运算器(3)--完成
    用Silverlight打造位运算器(1)--制作简易工具条控件
    用Silverlight打造位运算器(2)--制作数字文本框控件
    Lucky Sequence[SRM403DIVI500]
    答复:“判断一个整数的二进制位中有多少个1”的提问
    Python 笔记(1)
    #define中的#、## && #@
  • 原文地址:https://www.cnblogs.com/staginner/p/2695141.html
Copyright © 2011-2022 走看看