题目描述

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)

输入格式

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

输出格式

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

输入样例

21

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

输出样例

6 1

2

题解

这题需要用字符串Hash和Hash表结合。

因为可以反转,所以我们要正倒序都求一遍Hash值,然后放到Hash表即可。

这里提一个细节:我们每次可以判断当前最多的不同子串数是否小于之前求的最多的不同子串数,如果小于,则不用继续判断了。这样不仅省时间,而且也会减少Hash表内的元素数量,从而减少空间,减少冲突概率。

#include <iostream>
#include <cstdio> #define MAX_N (200000 + 5) using namespace std; typedef unsigned long long ull;
typedef const unsigned long long cull; struct Node
{
int nxt;
ull val;
}; int n;
int a[MAX_N];
cull b = ;
ull pb[MAX_N], h1[MAX_N], h2[MAX_N];
const int mod = ;
int hd[mod + ], tot;
Node l[MAX_N << ];
int ans, cnt;
int k[MAX_N]; inline ull Value(int lt, int rt)
{
return min(h1[rt] - h1[lt - ] * pb[rt - lt + ], h2[lt] - h2[rt + ] * pb[rt - lt + ]);
} inline void Add(ull val)
{
l[++tot].val = val;
l[tot].nxt = hd[val % mod];
hd[val % mod] = tot;
return;
} bool Check(ull val)
{
for(register int i = hd[val % mod]; i; i = l[i].nxt)
{
if(l[i].val == val) return false;
}
Add(val);
return true;
} int main()
{
scanf("%d", &n);
for(register int i = ; i <= n; ++i)
{
scanf("%d", a + i);
}
pb[] = ;
for(register int i = , j = n; i <= n; ++i, --j)
{
pb[i] = pb[i - ] * b;
h1[i] = h1[i - ] * b + a[i];
h2[j] = h2[j + ] * b + a[j];
}
int tmp;
for(register int i = ; i <= n; ++i)
{
if(n / i < ans) break;
tmp = ;
for(register int j = ; j + i - <= n; j += i)
{
if(tmp + (n - j + ) / i < ans) break;
if(Check(Value(j, j + i - ))) ++tmp;
}
if(tmp > ans)
{
ans = tmp;
cnt = ;
k[cnt] = i;
}
else if(tmp == ans)
{
k[++cnt] = i;
}
}
printf("%d %d\n", ans, cnt);
for(register int i = ; i <= cnt; ++i)
{
printf("%d", k[i]);
if(i < cnt) putchar(' ');
}
return ;
}

参考程序

【题解】Beads的更多相关文章

  1. Necklace of Beads(polya计数)

    Necklace of Beads Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7451   Accepted: 3102 ...

  2. POJ1509 Glass Beads

    Glass Beads Time Limit: 3000MS   Memory Limit: 10000K Total Submissions: 4314   Accepted: 2448 Descr ...

  3. 【POJ1509】Glass Beads

    [POJ1509]Glass Beads [题目描述]给定字符串S,并规定首尾相连成环,求出最小字典序. [输入]输入有多个数据,第一行只包括正整数N,表示有N组数据.每个数据包括一行,输入该字符串. ...

  4. POI2010题解

    POI2010题解 我也不知道我为什么就开始刷POI了 有些题目咕掉了所以不完整(我都不知道POI到底有多少题) [BZOJ2079][Poi2010]Guilds (貌似bz跟洛谷上的不是一个题?) ...

  5. bzoj 2081 [Poi2010]Beads hash+调和级数

    2081: [Poi2010]Beads Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1003  Solved: 334[Submit][Statu ...

  6. hdu 1817 Necklace of Beads(Polya定理)

    Necklace of Beads Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  7. 【BZOJ2081】[Poi2010]Beads hash+调和级数

    [BZOJ2081][Poi2010]Beads Description Zxl有一次决定制造一条项链,她以非常便宜的价格买了一长条鲜艳的珊瑚珠子,她现在也有一个机器,能把这条珠子切成很多块(子串), ...

  8. Beads

    Beads 题目描述 Zxl有一次决定制造一条项链,她以非常便宜的价格买了一长条鲜艳的珊瑚珠子,她现在也有一个机器,能把这条珠子切成很多块(子串),每块有k(k>0)个珠子,如果这条珠子的长度不 ...

  9. 题解【UVA10054】The Necklace

    题目描述 输入格式 输出格式 题意简述 有一种由彩色珠子连接而成的项链.每个珠子的两半由不同颜色组成.如图所示,相邻两个珠子在接触的地方颜色相同.现在有一些零碎的珠子,需要确认它们是否可以复原成完整的 ...

随机推荐

  1. 使用git、git-flow与gitlab工作

    使用git.git-flow与gitlab工作 1. 摘要 在工作中使用git代替svn也有一段时间了,对于git的一些特性喜爱的同时也一直遇到相同的问题:“这时候应该打什么命令?”.相对于svn或者 ...

  2. Quartz实现数据库动态配置定时任务

    项目实战 或许实现的方式跟之前的代码有点不一样的 1.定时任务的配置信息 @Configuration public class ScheduleConfigration { @Autowired p ...

  3. XMPP即时通讯协议使用(八)——基于订阅发布实现消息流转业务泳道图

  4. 2018-8-10-win10-uwp-毛玻璃

    title author date CreateTime categories win10 uwp 毛玻璃 lindexi 2018-08-10 19:16:50 +0800 2018-2-13 17 ...

  5. socket - Linux 套接字

    总览 #include <sys/socket.h> mysocket = socket(int socket_family, int socket_type, int protocol) ...

  6. android5.1修改系统默认音量

    在做定制需求的时候,需要修改系统通知的声音,将其禁用掉,避免第三方应用发送通知时,声音很大,吓着用户.索性就把通知声音关掉.下面就说说关闭声音的几种方法,以及修改系统默认声音的方法. 1. 直接修改系 ...

  7. nginx日志切割脚本shell

    nginx-log-rotate.sh: #!/bin/bash#---------------------------------------------# Comment:Used for rot ...

  8. django框架常用的数据库迁移命令

    python manage.py makemigrations 默认所有修改过的model层转为迁移文件 python manage.py migrate   默认将所有的迁移文件都执行,更新数据库 ...

  9. 【归纳】Layui table.render里的json后台传入

    在使用Layui的table元素时,传入的json的数据格式是有其自身定义的,需要另外添加一些字符,以正确传入. 为了传入符合前端格式的数据: table.render({ elem: '#test' ...

  10. 第04章 AOP概述

    第04章 AOP概述 1.AOP概述 ●AOP(Aspect-Oriented Programming,面向切面编程):是一种新的方法论,是对传统 OOP(Object-Oriented Progra ...