BZOJ-2081-[Poi2010]Beads(hash+暴力)

Description

Zxl有一次决定制造一条项链,她以非常便宜的价格买了一长条鲜艳的珊瑚珠子,她现在也有一个机器,能把这条珠子切成很多块(子串),每块有k(k>0)个珠子,如果这条珠子的长度不是k的倍数,最后一块小于k的就不要拉(nc真浪费),保证珠子的长度为正整数。 Zxl喜欢多样的项链,为她应该怎样选择数字k来尽可能得到更多的不同的子串感到好奇,子串都是可以反转的,换句话说,子串(1,2,3)和(3,2,1)是一样的。写一个程序,为Zxl决定最适合的k从而获得最多不同的子串。 例如:这一串珠子是: (1,1,1,2,2,2,3,3,3,1,2,3,3,1,2,2,1,3,3,2,1), k=1的时候,我们得到3个不同的子串: (1),(2),(3) k=2的时候,我们得到6个不同的子串: (1,1),(1,2),(2,2),(3,3),(3,1),(2,3) k=3的时候,我们得到5个不同的子串: (1,1,1),(2,2,2),(3,3,3),(1,2,3),(3,1,2) k=4的时候,我们得到5个不同的子串: (1,1,1,2),(2,2,3,3),(3,1,2,3),(3,1,2,2),(1,3,3,2)

Input

共有两行,第一行一个整数n代表珠子的长度,(n<=200000),第二行是由空格分开的颜色ai(1<=ai<=n)。

Output

也有两行,第一行两个整数,第一个整数代表能获得的最大不同的子串个数,第二个整数代表能获得最大值的k的个数,第二行输出所有的k(中间有空格)。

Sample Input

21

1 1 1 2 2 2 3 3 3 1 2 3 3 1 2 2 1 3 3 2 1

Sample Output

6 1

2

HINT

Source

题解

枚举长度,哈希暴力。

但是——————

被这道题坑了好久,模数怎么取交上去都WA,本来自己是正着和倒着都判一遍,后来参考了hzw学长的代码发现可以乘起来,这样正确率会高很多

这里有一个小优化:如果当前最大值乘上枚举的长度大于n的话,就可以直接break了

P.s.第一道权限题,用某人的号交的0.0

 1 #include<bits/stdc++.h>
 2 #define N 200005
 3 #define mod 998532737
 4 #define ll long long
 5 using namespace std;
 6 const ll x=12138;
 7 int n,Max,tot,num;
 8 int a[N],t[N];
 9 ll b[N],h1[N],h2[N];
10 map<ll,bool> mp;
11 int main(){
12     scanf("%d",&n);
13     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
14     b[0]=1;
15     for (int i=1;i<=n;i++) b[i]=(b[i-1]*x)%mod;
16     for (int i=1;i<=n;i++) h1[i]=(h1[i-1]*x+a[i])%mod;
17     for (int i=n;i>=1;i--) h2[i]=(h2[i+1]*x+a[i])%mod;
18     for (int k=1;k<=n;k++){
19         mp.clear();
20         if (n<Max*k) break;
21         num=0;
22         for (int i=1;i<=n/k;i++){
23             ll s1=((h1[i*k]-h1[(i-1)*k]*b[k])%mod+mod)%mod,s2=((h2[(i-1)*k+1]-h2[i*k+1]*b[k])%mod+mod)%mod;
24             if (!mp[s1*s2]){
25                 num++;
26                 mp[s1*s2]=true;
27             }
28         }
29         if (num>Max) Max=num,tot=1,t[1]=k; else
30         if (num==Max) t[++tot]=k;
31     }
32     printf("%d %d\n",Max,tot);
33     for (int i=1;i<=tot-1;i++)
34         printf("%d ",t[i]);
35     printf("%d\n",t[tot]);
36     return 0;
37 }

时间: 2024-11-02 12:11:43

BZOJ-2081-[Poi2010]Beads(hash+暴力)的相关文章

BZOJ 2801 Poi2010 Beads Hash

题目大意:给定一个数字串,求所有的k满足当将这个数字串从左到右分成大小为k的块时不同的块数量最多 反转同构算一种 枚举k,对于每个k将不同的串插入哈希表去重 反转同构啥的每个串的哈希值乘一下反串的哈希值就行了 时间复杂度O(n/1+n/2+...+n/n)=O(nlogn) #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 20020

BZOJ 2085 [Poi2010]Hamsters Hash+倍增floyd

题意:链接 方法: Hash+倍增floyd 解析: 首先这个BZ的无脑翻译我真是受不了. 加俩条件 所有串的长度总和不超过100000,并且对于任意不同子串A,B,A不包含于B,B不包含于A. 然后可以做题了. 首先,我们可以暴力hash搞出来如果i串后面接j串则需要增加多少长度. 这个n非常的小所以直接开数组记录. 然后就是倍增floyd了. 至于前半部分为什么是复杂度可以接受的. 参见PoPoQQQ的证明,总之我们要求的 ∑∑(min(leni,lenj))的函数的最大化时,复杂度是O(l

【bzoj2081】[Poi2010]Beads Hash

题目描述 Zxl有一次决定制造一条项链,她以非常便宜的价格买了一长条鲜艳的珊瑚珠子,她现在也有一个机器,能把这条珠子切成很多块(子串),每块有k(k>0)个珠子,如果这条珠子的长度不是k的倍数,最后一块小于k的就不要拉(nc真浪费),保证珠子的长度为正整数. Zxl喜欢多样的项链,为她应该怎样选择数字k来尽可能得到更多的不同的子串感到好奇,子串都是可以反转的,换句话说,子串(1,2,3)和(3,2,1)是一样的.写一个程序,为Zxl决定最适合的k从而获得最多不同的子串. 例如:这一串珠子是: (

hdu 4886 TIANKENG’s restaurant(2)(hash+暴力)

题目链接:hdu 4886 TIANKENG's restaurant(2) 题目大意:给定一个字符串S,要求在该字符串中找到一个最短并且字符串字典序最小. 解题思路:每次枚举字符串的长度,然后将S中所有该长度的子串映射成一个9进制数,最后再遍历一遍标记数组. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1000005; i

BZOJ2081 [Poi2010]Beads

我们只要暴力枚举块的大小就可以了... 枚举的总复杂度是O(n / 1 + n / 2 + n / 3 + ...) = O(n * logn)的 何如去重呢...直接暴力hash再丢进set里搞定,总复杂度O(n * log2n) 1 /************************************************************** 2 Problem: 2081 3 User: rausen 4 Language: C++ 5 Result: Accepted 6

BZOJ 3790 神奇项链 hash/后缀自动机+贪心

Description 母亲节就要到了,小 H 准备送给她一个特殊的项链.这个项链可以看作一个用小写字母组成的字符串,每个小写字母表示一种颜色. 为了制作这个项链,小 H 购买了两个机器.第一个机器可以生成所有形式的回文串,第二个机器可以把两个回文串连接起来,而且第二个机器还有一个特殊的性质:假如一个字符串的后缀和一个字符串的前缀是完全相同的,那么可以将这个重复部分重叠.例如:aba和aca连接起来,可以生成串abaaca或 abaca. 现在给出目标项链的样式,询问你需要使用第二个机器多少次才

垃圾佬的旅游III(Hash + 暴力)

题目链接:http://120.78.128.11/Problem.jsp?pid=3445 最开始的思路就是直接暴力求解,先把所有的数值两两存入结构体,再从小到大枚举.用二分的思路去判断数值以及出现,结果TLE,但优化一下应该也能过,因为题目说只有两组数据.代码如下: 1 #include <iostream> 2 #include <string> 3 #include <cstdio> 4 #include <cstdlib> 5 #include &

单调队列 BZOJ 2096 [Poi2010]Pilots

2096: [Poi2010]Pilots Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 819  Solved: 418[Submit][Status][Discuss] Description Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值.耍畸形一个人是不行的,于是他找到了你. Input 输入:第一行两个有空格隔开的整数k(0

BZOJ 2086: [Poi2010]Blocks

2086: [Poi2010]Blocks Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 494  Solved: 222[Submit][Status][Discuss] Description 给出N个正整数a[1..N],再给出一个正整数k,现在可以进行如下操作:每次选择一个大于k的正整数a[i],将a[i]减去1,选择a[i-1]或a[i+1]中的一个加上1.经过一定次数的操作后,问最大能够选出多长的一个连续子序列,使得这个子序列的每个数