JZOJ4860【NOIP2016提高A组集训第7场11.4】分解数
2016-11-04 20:37
393 查看
Description
Dpstr学习了动态规划的技巧以后,对数的分解问题十分感兴趣。Dpstr用此过程将一个正整数x分解成若干个数的乘积:一开始令集合A中只有一个元素x,每次分解时从A中取一个元素a并找出两个大于1且互质的整数p,q,要求pq=a,然后将a分解成两个元素p和q,也就是从A中删去a并加入p和q。Dpstr把正整数x用该过程能分解的次数的最大值称为x的分解数。
例如66的分解数为2,因为最多分解2次。一种分解过程为:一开始A={66},第1次将66分解为11×6,此时A={11,6},第2次将6分解为2×3,此时A={11,2,3},之后无法分解。还可以知道,11,2,3的分解数均为0,因为它们一开始就无法分解。
不过只分解一个数对Dpstr来说不够有趣。Dpstr生成了一个包含n个正整数的数列a1, a2, …, an,请你回答有多少对正整数(l,r)满足1≤l≤r≤n且lcm(al, al+1, …, ar-1, ar)的分解数恰为k。其中lcm(al, al+1, …, ar-1, ar)表示数列从第l项到第r项的所有数的最小公倍数,特别地,当l=r时,lcm(al)=al。由于答案可能很大,只需输出满足条件的正整数对个数除以10,007的余数。
Data Constraint
对于20%的数据,1≤n≤10,1≤k≤5,1≤ai≤20;对于40%的数据,1≤n≤100,1≤k≤10,1≤ai≤100;
对于60%的数据,1≤n≤1,000,1≤k≤1,000,1≤ai≤100,000;
对于100%的数据,1≤n≤1,000,000,1≤k≤5,000,000,1≤ai≤10,000,000。
Solution
这道题实质就是求有多少个区间的lcm的分解质因数后的个数恰为m+1。由于对于一个右端点,它的左端点的答案是有二分性的,所以我们考虑用指针。对于一个右端点k,我们设左端点的两个指针分别为i,j,表示左端点在[i,j]内的答案为m+1。同时我们打两个桶,记录[i,k]和[j,k]的lcm有多少质因子,动态维护一下使[i,j]始终合法即可。
现在我们再来考虑一下怎样预处理。我们先用欧拉筛处理处10,000,000内的质数,同时处理处每个数的最小质因子。对于每个输入的数,我们不断除以这个数的最小质因数。所以复杂度为O(N*logN)。
Code
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #include<algorithm> #define ll long long using namespace std; const int maxn1=10000000,maxn2=1000000; int g[maxn2],g1[maxn2]; int b[maxn2][9],d[maxn2],xiao[maxn1]; int n,i,t,j,k,l,m,sum,x,ans,sum1; bool bz[maxn1+5],bz1; int main(){ freopen("dec.in","r",stdin);freopen("dec.out","w",stdout); // freopen("data.in","r",stdin); bz[1]=true; for (i=2;i<=maxn1;i++){ if (!bz[i]) d[++d[0]]=i,xiao[i]=d[0]; for (j=1;j<=d[0];j++){ if (i*d[j]>maxn1) break; bz[i*d[j]]=true; xiao[i*d[j]]=min(j,xiao[i]); if (!(i%d[j])) break; } } scanf("%d%d",&n,&m); m++; for (i=1;i<=n;i++){ scanf("%d",&t); while (t>1){ k=xiao[t]; b[i][++b[i][0]]=xiao[t]; while (!(t%d[k])) t/=d[k]; } } i=1;j=1; for (k=1;k<=n;k++){ t=0; for (l=1;l<=b[k][0];l++){ if (!g[b[k][l]]) sum++; g[b[k][l]]++; if (!g1[b[k][l]]) sum1++; g1[b[k][l]]++; } if (sum>=m){ while (sum>m){ for (l=1;l<=b[i][0];l++){ g[b[i][l]]--; if (!g[b[i][l]]) sum--; } i++; } if (sum==m){ bz1=true; while (1){ for (l=1;l<=b[j][0];l++){ g1[b[j][l]]--; if (!g1[b[j][l]]) sum1--; } if (sum1<m){ for (l=1;l<=b[j][0];l++){ if (!g1[b[j][l]]) sum1++; g1[b[j][l]]++; } break; } j++; } if (j>=i) ans+=j-i+1; } ans=ans%10007; }else sum+=t; } printf("%d\n",ans); }
相关文章推荐
- 【JZOJ4860】【NOIP2016提高A组集训第7场11.4】分解数
- JZOJ4861【NOIP2016提高A组集训第7场11.4】推冰块
- 【JZOJ4859】【NOIP2016提高A组集训第7场11.4】连锁店
- 【NOIP2016提高A组集训第7场11.4】分解数
- JZOJ4859. 【NOIP2016提高A组集训第7场11.4】连锁店
- 【NOIP2016提高A组集训第7场11.4】连锁店
- 【NOIP2016提高A组集训第7场11.4】推冰块
- 【JZOJ4861】【NOIP2016提高A组集训第7场11.4】推冰块
- JZOJ 4824. 【NOIP2016提高A组集训第1场10.29】配对游戏
- JZOJ4854【NOIP2016提高A组集训第6场11.3】小澳的坐标系
- 【JZOJ4882】【NOIP2016提高A组集训第12场11.10】多段线性函数
- 【JZOJ4886】【NOIP2016提高A组集训第13场11.11】字符串
- JZOJ4890. 【NOIP2016提高A组集训第14场11.12】随机游走
- JZOJ 4823. 【NOIP2016提高A组集训第1场10.29】小W学物理
- JZOJ4899. 【NOIP2016提高A组集训第17场11.16】雪之国度
- JZOJ4869【NOIP2016提高A组集训第9场11.7】平均数
- JZOJ 4866 【NOIP2016提高A组集训第8场11.5】禅与园林艺术
- JZOJ 4879 【NOIP2016提高A组集训第11场11.9】少女觉
- 【JZOJ4899】【NOIP2016提高A组集训第17场11.16】雪之国度
- JZOJ4876. 【NOIP2016提高A组集训第10场11.8】基因突变(2017.8B组)