• BZOJ_2795_[Poi2012]A Horrible Poem_hash+暴力


    Description


    给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节。
    如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到。

    Input

    第一行一个正整数n (n<=500,000),表示S的长度。
    第二行n个小写英文字母,表示字符串S。
    第三行一个正整数q (q<=2,000,000),表示询问个数。
    下面q行每行两个正整数a,b (1<=a<=b<=n),表示询问字符串S[a..b]的最短循环节长度。

    Output

    依次输出q行正整数,第i行的正整数对应第i个询问的答案。

    Sample Input

    8
    aaabcabc
    3
    1 3
    3 8
    4 8

    Sample Output

    1
    3
    5

    我们现在要求[L,R]的最短循环节,假设长度为x。
    那么满足[L+x,R]和[L,R-x]两个子串是相等的,这一步可以用hash解决。
    随机询问n次某个数的约数个数这个是期望$O(nln)$的,上限是$O(nsqrt n)$。
    所以我们先把每个数的约数处理出来,存到vector中,这一步也是$O(nln)$的。
    询问时暴力枚举约数即可。
    然后hash用unsigned int自然溢出,卡一卡就过了。
     
    代码:
    // luogu-judger-enable-o2
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <vector>
    using namespace std;
    #define N 500050
    #define RR register
    __attribute__((optimize("-O2")))inline char nc() {
        static char buf[100000],*p1,*p2;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    __attribute__((optimize("-O2")))inline int rd() {
        RR int x=0;RR char c=nc();
        while(c<'0'||c>'9') c=nc();
        while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=nc();
        return x;
    }
    __attribute__((optimize("-O2")))inline int rc() {
        RR char c=nc();
        while(c<'a'||c>'z') c=nc();
        return (int)c;
    }
    typedef unsigned int ll;
    int n,m;
    int s[N];
    ll h[N],mi[N],base=19260817;
    vector<int>q[N];
    __attribute__((optimize("-O2")))inline ll get_hash(int l,int r) {
        return h[r]-h[l-1]*mi[r-l+1];
    }
    __attribute__((optimize("-O2")))inline int solve(int l,int r) {
        int len=r-l+1,i;
        int siz=q[len].size();
        for(i=0;i<siz;i++) {
            int x=q[len][i];
            if(get_hash(l+x,r)==get_hash(l,r-x)) return x;
        }
    }
    char pbuf[10000000] , *pp = pbuf;
    inline void write(int x)
    {
        static int sta[20];
        RR int top = 0;
        if(!x)sta[++top]=0;
        while(x) sta[++top] = x % 10 , x /= 10;
        while(top) *pp ++ = sta[top -- ] ^ '0';
    }
    __attribute__((optimize("-O2")))int main() {
        RR int i,x,y,j;
        n=rd();
        for(i=1;i<=n;i++) s[i]=rc(); 
        m=rd();
        for(mi[0]=1,i=1;i<=n;i++) {
            h[i]=h[i-1]*base+s[i];
            mi[i]=mi[i-1]*base;
        }
        for(i=1;i<=n;i++) {
            for(j=i;j<=n;j+=i) {
                q[j].push_back(i);
            }
        }
        while(m--) {
            x=rd(); y=rd();
            write(solve(x,y));*pp ++ ='
    ';
        }
        fwrite(pbuf , 1 , pp - pbuf , stdout);
    }
    /*
    8
    aaabcabc
    3
    1 3
    3 8
    4 8
    */
    
  • 相关阅读:
    ubuntu中source insight打不开,报错pagefault的解决方法
    第六次团队作业——Alpha冲刺之事后诸葛亮
    Alpha阶段总结
    第五次团队作业——第一次项目冲刺——Alpha版本
    第四次团队作业——系统设计
    团队项目——需求规格说明书
    第二次团队作业——预则立&&他山之石
    团队项目时间规划2016
    第二次结对编程作业——毕设导师智能匹配
    第二次团队作业——团队选题报告
  • 原文地址:https://www.cnblogs.com/suika/p/9062452.html
Copyright © 2020-2023  润新知