博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj 2081 [Poi2010]Beads hash+调和级数
阅读量:4981 次
发布时间:2019-06-12

本文共 2505 字,大约阅读时间需要 8 分钟。

2081: [Poi2010]Beads

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 1003  Solved: 334
[][][]

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
 
题解:
   hash可以O(1)求一个字符串的hash值,然后调和级数分析复杂度即可。
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 9 #define N 100000710 #define B 20000111 #define ll long long12 13 #define Wb putchar(' ')14 #define We putchar('\n')15 #define rg register int16 using namespace std;17 inline int read()18 {19 int x=0,f=1;char ch=getchar();20 while(!isdigit(ch)){ if(ch=='-')f=-1;ch=getchar();}21 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}22 return x*f;23 }24 inline void write(int x)25 {26 if(x<0) putchar('-'),x=-x;27 if (x==0) putchar(48);28 int num=0;char c[15];29 while(x) c[++num]=(x%10)+48,x/=10;30 while(num) putchar(c[num--]);31 }32 33 unsigned ll mul[N],s1[N],s2[N];34 int n,mx;35 int a[N];36 map
mp;37 vector
k;38 39 unsigned ll gethash(int l,int r)40 {41 unsigned ll t;42 if (l<=r) t=s1[r]-s1[l-1]*mul[r-l+1];43 else t=s2[r]-s2[l+1]*mul[l-r+1];44 return t;45 }46 void solve(int x)47 {48 if(mx*x>n) return;49 int ans=0;50 mp.clear();51 for(int i=1;i<=n;i+=x)52 if(i+x-1<=n)53 {54 unsigned ll t=gethash(i,i+x-1)*gethash(i+x-1,i);55 if (mp[t]) continue;56 else ans++;57 mp[t]=1;58 }59 if(ans>mx) mx=ans,k.clear();60 if(ans==mx) k.push_back(x);61 }62 int main()63 {64 n=read();65 for (int i=1;i<=n;i++) a[i]=read();66 mul[0]=1;for (int i=1;i<=n;i++) mul[i]=mul[i-1]*B;67 for(int i=1;i<=n;i++)68 s1[i]=s1[i-1]*B+a[i];69 for(int i=n;i>=1;i--)70 s2[i]=s2[i+1]*B+a[i];71 for(int i=1;i<=n;i++)solve(i);72 printf("%d %lu\n",mx,k.size());73 for(int i=0;i

 

转载于:https://www.cnblogs.com/fengzhiyuan/p/8983594.html

你可能感兴趣的文章
c#中ObservableCollection<T>排序方法
查看>>
Vue.Js
查看>>
炫酷的手风琴效果
查看>>
面试官:你是如何使用JDK来实现自己的缓存(支持高并发)?
查看>>
iOS开发 代码 或 <Home+Power>截屏
查看>>
字符编码大纲
查看>>
使Python中的turtle模块画图两只小羊
查看>>
阿里云数据库Redis版 ERR invalid password
查看>>
z-index坑
查看>>
javascript基础学习五-原型prototype
查看>>
C++类实现AVL树
查看>>
使用spacedesk实现两台笔记本的双屏显示
查看>>
解决 Javascript 中 atob 方法解码中文字符乱码问题
查看>>
Tomcat使用线程池配置高并发连接
查看>>
iOS----------输入框UITextField禁止输入空格
查看>>
Windows Phone 学习教程(一)
查看>>
整合Solr与tomcat以及第一个core的配置
查看>>
读写应用程序数据-CoreData
查看>>
贝多芬音乐
查看>>
SRM 20
查看>>