BZOJ-3647: 密码破译(HASH)

作者: acccccc | 来源:发表于2019-03-15 09:59 被阅读0次

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3647

首先我们发现要是可以分成n块,那么对于任意d|n,都可以分成d块,所以枚举长度的质因数,然后HASH判一下成不成立,最后乘起来就好啦,预处理的话质因数分解是log n的,所以总复杂度是O(n log n)-O(log n)。

代码(200W查询多么可怕,POI原题即视感):

#include <cstdio>

#include <algorithm>

#include <cstring>

#include <cmath>

#include <vector>

 

using namespace std ;

 

typedef long long ll ;

 

const int p = 31 , P = 1000173169 ;

const int maxn = 501000 ;

 

char s[ maxn ] ;

int n , m ;

 

bool flag[ maxn ] ;

vector < int > vec[ maxn ] ;

int prm[ maxn ] , pn = 0 ;

 

inline int power( int x , int cnt ) {

        int y = 1 ;

        for ( ; cnt ; cnt >>= 1 ) {

                if ( cnt & 1 ) y = ( ll ) y * x % P ;

                x = ( ll ) x * x % P ;

        }

        return y ;

}

 

int mul[ maxn ] , pre[ maxn ] ;

 

inline void Init(  ) {

        memset( flag , true , sizeof( flag ) ) ;

        for ( int i = 2 ; i <= n ; ++ i ) {

                if ( flag[ i ] ) prm[ ++ pn ] = i ;

                for ( int j = 1 ; i * prm[ j ] <= n && j <= pn ; ++ j ) {

                        flag[ i * prm[ j ] ] = false ;

                        if ( ! ( i % prm[ j ] ) ) break ;

                }

        }

        for ( int i = 0 ; i ++ < pn ; ) {

                for ( int j = prm[ i ] ; j <= n ; j += prm[ i ] ) vec[ j ].push_back( prm[ i ] ) ;

        }

        mul[ 0 ] = 1 ;

        for ( int i = 0 ; i ++ < n ; ) mul[ i ] = ( ll ) mul[ i - 1 ] * p % P ;

        pre[ 0 ] = 0 ;

        for ( int i = 0 ; i ++ < n ; ) pre[ i ] = ( ( ( ll ) pre[ i - 1 ] * p % P ) + ( s[ i ] - 'a' ) ) % P ;

}

 

inline int query( int l , int r ) {

        if ( l > r ) return 0 ;

        int sum = ( ll ) pre[ l - 1 ] * mul[ r - l + 1 ] % P ;

        sum = ( pre[ r ] - sum + P ) % P ;

        return sum ;

}

 

inline bool check( int l , int r , int x ) {

        return query( l , r - x ) == query( l + x , r ) ;

}

 

inline int Query( int l , int r ) {

        int len = r - l + 1 , cnt = 1 , y , z ;

        for ( vector < int > :: iterator i = vec[ len ].begin(  ) ; i != vec[ len ].end(  ) ; ++ i ) {

                for ( y = 1 ; ; ) {

                        if ( ! ( len % ( z = y * *i ) ) ) {

                                if ( check( l , r , len / z ) ) y = z ; else break ;

                        } else break ;

                }

                cnt *= y ;

        }

        return len / cnt ;

}

 

int main(  ) {

        scanf( "%d" , &n ) ; scanf( "%s" , s + 1 ) ;

        Init(  ) ;

        scanf( "%d" , &m ) ;

        while ( m -- ) {

                int l , r ; scanf( "%d%d" , &l , &r ) ; printf( "%d\n" , Query( l , r ) ) ;

        }

        return 0 ;

}

相关文章

  • BZOJ-3647: 密码破译(HASH)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3647 首...

  • 老君详谈地球游戏“诡道”的秘密

    其实,地球游戏,我们就是破译它。你们现在在破译地球游戏的密码。密码很简单,不是密码多的很,真正的那组密码就在你那儿...

  • 破译密码

    罗光富 我给她一段复杂的密码 她花了十个月的时间 终于破译出来 她循着'这些信息 找到了几十年前的我

  • 破译密码

    “看来,此女不可高攀!我不是你的菜!”他扔下一句话后,转瞬消失得无影无踪,她偷着乐。 他问她联系方式,她忽然心生顽...

  • 故宫的风花雪月破译古典书画的生命密码 祝勇著

    故宫的风花雪月破译古典书画的生命密码 祝勇著 书籍名称 :故宫的风花雪月破译古典书画的生命密码 编著人员 :祝勇著...

  • 破译不良行为密码,和善而坚定共成长

    破译不良行为密码,和善而坚定共成长一一《正面管教》第4章“重新看待不良行为”阅读心得 破译不良行为密码,和善而坚定...

  • Net-NTLM hash利用方法

    一、windows的hash NTLM hash NTLM hash是windows登录密码的一种hash,可以在...

  • 俞敏洪母亲:背后的教子读书故事之思(上)

    俞敏洪母亲:背后的教子读书故事之思(上) ——破译俞敏洪母亲教子之密码 (注破译俞敏洪母亲教子之密码此文 为201...

  • 读《破译疾病密码》

    《破译疾病密码》对以往医学大厦进行了补充,并试图以其独特的见解使现代人对疾病的认识受到一点震动。 《破译疾病密码》...

  • 破译天赋密码

    因为参加易效能PPT的学习,有缘认识了来自宝岛台湾的天赋密码教练马丁老师。记得在24期PPT班的结业典礼上,马丁老...

网友评论

    本文标题:BZOJ-3647: 密码破译(HASH)

    本文链接:https://www.haomeiwen.com/subject/sookmqtx.html