【PA2013】【BZOJ3837】Filary
2016-03-30 11:27
246 查看
Description
给定n个正整数,从中挑出k个数,满足:存在某一个m(m>=2),使得这k个数模m的余数相等。
求出k的最大值,并求出此时的m。如果有多组解使得k最大,你要在此基础上求出m的最大值。
Input
第一行一个正整数n(2<=n<=10^5)。
第二行n个正整数wi。保证不会出现所有w[i]都相等的情况。
Output
一行两个整数k,m。保证答案存在。
Sample Input
6
7 4 10 8 7 1
Sample Output
5 3
HINT
Source
这题好厉害呀QAQ
首先可以发现答案k最小也得是n2,感觉可以用奇怪的姿势乱搞?但是我的姿势水平并不足够想出正确的乱搞算法
然后就翻了zky的提交记录和Claris的题解QAQ
因为答案最小是n2,所以这就意味着一个数至少也有12的概率在被选中的k个数里,所以可以设计一个随机+Hash的做法.
每次随机找一个数ai,将这个数作为必选的k个数之一,然后用其他数对其作差,对差值分解质因数.
我们考虑找出分解出的质因数里出现次数最多的那个数,每个数我们都可以看成是拆分为ai+delta,考虑对取模后的结果得贡献ai部分都是一样的,然后delta有相同质因数的,对那个质因数取模后贡献是一样的(0),所以出现次数最多的那个质因数的出现次数再加上ai出现的次数就是最优情况下的k.
对于那个固定的k找一个m,只需要把那些找到的所有对应位置的因数乘一下,然后看一看总共出现过哪些结果,找到最小的那个.
对于数目的统计,可以对每个数给一个随机hash值,异或起来求出hash值,然后排序扫一遍.
如果你觉得我写的口胡根本看不懂的话..Claris题解传送门
你也可以直接从QQ上找Claris问.(我怕我口胡错掉QAQ)
最后,今天是3.30,蓝月亮lct1999的生日,代码里粗线了奇怪的东西!
给定n个正整数,从中挑出k个数,满足:存在某一个m(m>=2),使得这k个数模m的余数相等。
求出k的最大值,并求出此时的m。如果有多组解使得k最大,你要在此基础上求出m的最大值。
Input
第一行一个正整数n(2<=n<=10^5)。
第二行n个正整数wi。保证不会出现所有w[i]都相等的情况。
Output
一行两个整数k,m。保证答案存在。
Sample Input
6
7 4 10 8 7 1
Sample Output
5 3
HINT
Source
这题好厉害呀QAQ
首先可以发现答案k最小也得是n2,感觉可以用奇怪的姿势乱搞?但是我的姿势水平并不足够想出正确的乱搞算法
然后就翻了zky的提交记录和Claris的题解QAQ
因为答案最小是n2,所以这就意味着一个数至少也有12的概率在被选中的k个数里,所以可以设计一个随机+Hash的做法.
每次随机找一个数ai,将这个数作为必选的k个数之一,然后用其他数对其作差,对差值分解质因数.
我们考虑找出分解出的质因数里出现次数最多的那个数,每个数我们都可以看成是拆分为ai+delta,考虑对取模后的结果得贡献ai部分都是一样的,然后delta有相同质因数的,对那个质因数取模后贡献是一样的(0),所以出现次数最多的那个质因数的出现次数再加上ai出现的次数就是最优情况下的k.
对于那个固定的k找一个m,只需要把那些找到的所有对应位置的因数乘一下,然后看一看总共出现过哪些结果,找到最小的那个.
对于数目的统计,可以对每个数给一个随机hash值,异或起来求出hash值,然后排序扫一遍.
如果你觉得我写的口胡根本看不懂的话..Claris题解传送门
你也可以直接从QQ上找Claris问.(我怕我口胡错掉QAQ)
最后,今天是3.30,蓝月亮lct1999的生日,代码里粗线了奇怪的东西!
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define MAXN 100010 #define MAXV 10000010 #define SIZE 700000 #define GET (ch>='0'&&ch<='9') using namespace std; int n,k,m,cnt,tp,T; int a[MAXN],b[MAXN],maxn; bool not_prime[MAXV]; int prime[SIZE],top,id[MAXV],fac[MAXV]; int vis[SIZE],sta[40],pow; int pos[SIZE],lst[SIZE]; struct happy_birthday_lct1999 { int cnt,hash,num; happy_birthday_lct1999(){ hash=cnt=0;num=1; } happy_birthday_lct1999(int Cnt,int Hash,int Num) { cnt=Cnt;hash=Hash;num=Num; } inline bool operator <(const happy_birthday_lct1999 &a)const { return hash<a.hash; } }s[SIZE]; inline void in(int &x) { char ch=getchar();x=0; while (!GET) ch=getchar(); while (GET) x=x*10+ch-'0',ch=getchar(); } void check() { for (int i=2;i<=maxn;++i) { if (!not_prime[i]) prime[++top]=i,fac[i]=i,id[i]=top; for (int j=1;j<=top&&i*prime[j]<=maxn;++j) { fac[i*prime[j]]=prime[j];id[i*prime[j]]=j;not_prime[i*prime[j]]=1; if (i%prime[j]==0) break; } } } void solve(int x,int y) { int tmp=0,t=0; for (int i=1;i<=pow;++i) vis[sta[i]]=0;pow=0; for (;x!=1;vis[id[x]]*=fac[x],x/=fac[x]) if (!vis[id[x]]) vis[sta[++pow]=id[x]]=1; for (int i=1;i<=pow;++i) { tmp=vis[sta[i]]; if (lst[sta[i]]!=T) lst[sta[i]]=T,s[t=pos[sta[i]]=++tp]=happy_birthday_lct1999(0,0,tmp); else t=pos[sta[i]]; ++s[t].cnt;s[t].hash^=y;s[t].num=min(s[t].num,tmp); } } int main() { in(n);s[0].hash=-1; for (int i=1;i<=n;i++) { in(a[i]);maxn=max(maxn,a[i]); while (!b[i]) b[i]=rand(); } check(); for (T=1;T<=4;++T) { int x=a[rand()%n+1],i,j=0;cnt=tp=0; for (i=1;i<=n;i++) if (a[i]!=x) solve(max(a[i]-x,x-a[i]),b[i]); else cnt++; sort(s+1,s+tp+1); for (int i=1;i<=tp;++i) if (s[i].hash!=s[j].hash) { if (j) { if (s[j].cnt+cnt>k) k=s[j].cnt+cnt,m=s[j].num; else if (s[j].cnt+cnt==k&&s[j].num>m) m=s[j].num; } j=i; } else s[j].num*=s[i].num; if (s[j].cnt+cnt>k) k=s[j].cnt+cnt,m=s[j].num; else if (s[j].cnt+cnt==k&&s[j].num>m) m=s[j].num; } printf("%d %d\n",k,m); }
相关文章推荐
- c语言实现hashmap(转载)
- Ruby中Hash的11个问题解答
- Ruby简明教程之数组和Hash介绍
- 在C#中生成与PHP一样的MD5 Hash Code的方法
- js中hash和ico的关联分析
- Javascript SHA-1:Secure Hash Algorithm
- 理解php Hash函数,增强密码安全
- PHP利用hash冲突漏洞进行DDoS攻击的方法分析
- PowerShell中定义哈希散列(Hash)和调用例子
- Redis String 类型和 Hash 类型学习笔记与总结
- php操作redis中的hash和zset类型数据的方法和代码例子
- Perl 哈希Hash用法之入门教程
- perl哈希hash的常见用法介绍
- php自定义hash函数实例
- php对文件进行hash运算的方法
- php常用hash加密函数
- PHP Hash算法:Times33算法代码实例
- php的hash算法介绍
- memcache一致性hash的php实现方法
- Mysql中的Btree与Hash索引比较