【JZOJ4860】【NOIP2016提高A组集训第7场11.4】分解数
题目描述
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的余数。
数据范围
对于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。
解法
对于i维护极大区间[l,r]使得,[i,l]的lcm的分解数为k,[i,r]的lcm的分解数为k。 
那么答案就是所有的i的区间长度。
由于当i右移时,区间[l,r]不可能左移。 
所以利用单调性来维护这段区间。 
维护一个桶,表示在[i,l]和[i,r]中各个素数的个数,就容易得出一段区间lcm的分解数。
以上维护本身只需O(n),但分解质因数需要O(n1.5)。 
考虑使用线筛优化分解质因数。 
使用线筛得出每个数的最小值因子。 
那么分解质因数总共只需O(nlogn)
代码
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define ll long long
using namespace std;
const char* fin="dec.in";
const char* fout="dec.out";
const int inf=0x7fffffff;
const int maxn=1000007,maxa=10000007,maxc=664580,mo=10007;
int n,m,i,j,k,l,r;
int a[maxn];
int f[maxa],c[maxc];
int L[maxc],R[maxc];
int p[maxn][9],cnt[maxn][9];
ll ans;
void work(int l){
    if (!p[l][0]){
        while (a[l]!=1){
            if (!p[l][0] || f[a[l]]!=p[l][p[l][0]]){
                p[l][++p[l][0]]=f[a[l]];
            }
            cnt[l][p[l][0]]++;
            a[l]/=c[p[l][p[l][0]]];
        }
    }
}
int main(){
    freopen(fin,"r",stdin);
    freopen(fout,"w",stdout);
    scanf("%d%d",&n,&m);
    m++;
    f[1]=0;
    for (i=2;i<maxa;i++){
        if (!f[i]){
            c[++c[0]]=i;
            f[i]=c[0];
        }
        for (j=1;j<=c[0];j++){
            k=i*c[j];
            if (k>=maxa) break;
            f[k]=j;
            if (i%c[j]==0) break;
        }
    }
    for (i=1;i<=n;i++) scanf("%d",&a[i]);
    l=r=0;
    for (i=1;i<=n;i++){
        while (L[0]<m){
            if (l==n){
                printf("%lld",ans);
                return 0;
            }
            work(++l);
            for (j=1;j<=p[l][0];j++){
                L[p[l][j]]+=cnt[l][j];
                if (L[p[l][j]]==cnt[l][j]) L[0]++;
            }
        }
        while (r!=n+1 && R[0]<=m){
            if (r==n){
                r=n+1;
                break;
            }
            work(++r);
            for (j=1;j<=p[r][0];j++){
                R[p[r][j]]+=cnt[r][j];
                if (R[p[r][j]]==cnt[r][j]) R[0]++;
            }
        }
        ans=(ans+r-l)%mo;
        for (j=1;j<=p[i][0];j++){
            L[p[i][j]]-=cnt[i][j];
            if (!L[p[i][j]]) L[0]--;
            R[p[i][j]]-=cnt[i][j];
            if (!R[p[i][j]]) R[0]--;
        }
    }
    printf("%lld",ans);
    return 0;
}启发
这次也是所有区间问题。 
之前总结出,所有区间问题可以使用O(nlogn)分治。 
但在本题中显然不适用。
目前看来,所有区间问题有如下方法: 
1.分治,O(nlogn) 
2.动态规划,O(n) 
3.维护单调区间,O(n)
线性筛法:分析。 
可以用于优化分解质因数。
【JZOJ4860】【NOIP2016提高A组集训第7场11.4】分解数的更多相关文章
- JZOJ 【NOIP2016提高A组集训第16场11.15】兔子
		JZOJ [NOIP2016提高A组集训第16场11.15]兔子 题目 Description 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3 ... 
- JZOJ 【NOIP2016提高A组集训第16场11.15】SJR的直线
		JZOJ [NOIP2016提高A组集训第16场11.15]SJR的直线 题目 Description Input Output Sample Input 6 0 1 0 -5 3 0 -5 -2 2 ... 
- 【NOIP2016提高A组集训第4场11.1】平衡的子集
		题目 夏令营有N个人,每个人的力气为M(i).请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法? 分析 如果暴力枚举每个人被分到哪 ... 
- 【JZOJ4841】【NOIP2016提高A组集训第4场11.1】平衡的子集
		题目描述 夏令营有N个人,每个人的力气为M(i).请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法? 数据范围 40%的数据满足: ... 
- 【NOIP2016提高A组集训第14场11.12】随机游走
		题目 YJC最近在学习图的有关知识.今天,他遇到了这么一个概念:随机游走.随机游走指每次从相邻的点中随机选一个走过去,重复这样的过程若干次.YJC很聪明,他很快就学会了怎么跑随机游走.为了检验自己是不 ... 
- 【NOIP2016提高A组集训第13场11.11】最大匹配
		题目 mhy12345学习了二分图匹配,二分图是一种特殊的图,其中的点可以分到两个集合中,使得相同的集合中的点两两没有连边. 图的"匹配"是指这个图的一个边集,里面的边两两不存在公 ... 
- 【NOIP2016提高A组集训第14场11.12】随机游走——期望+树形DP
		好久没有写过题解了--现在感觉以前的题解弱爆了,还有这么多访问量-- 没有考虑别人的感受,没有放描述.代码,题解也写得歪歪扭扭. 并且我要强烈谴责某些写题解的代码不打注释的人,像天书那样,不是写给普通 ... 
- 【JZOJ4901】【NOIP2016提高A组集训第18场11.17】矩阵
		题目描述 他是一名普通的农电工,他以一颗无私奉献的爱岗敬业之心,刻苦钻研业务,以娴熟的技术.热情周到的服务赢得了广大客户的尊敬和赞美.他就是老百姓称为"李电"的李春来. 众所周知, ... 
- 【JZOJ4898】【NOIP2016提高A组集训第17场11.16】人生的价值
		题目描述 NiroBC终于找到了人生的意义,可是她已经老了,在新世界,没有人认识她,她孤独地在病榻上回顾着自己平凡的一生,老泪纵横.NiroBC多么渴望再多活一会儿啊! 突然一个戴着黑色方框眼镜,方脸 ... 
随机推荐
- SpringBoot防XSS攻击
			1 . pom中增加依赖 <!-- xss过滤组件 --> <dependency> <groupId>org.jsoup</groupId> < ... 
- LINUX设置SUID,SGID,Stick bit
			前面介绍过SUID与SGID的功能,那么,如何打开文件使其成为具有SUID与SGID的权限呢?这就需要使用数字更改权限了.现在应该知道,使用数字 更改权限的方式为“3个数字”的组合,那么,如果在这3个 ... 
- agc014F Strange Sorting
			这套题比较简单,以为自己能够独立A掉D和E,或许就能自己A掉F,看来还真是想多了 题意:给一个$n$的全排列,每次操作把$max(a[1],a[2],...,a[i]) = a[i]$的记为$high ... 
- centos apache安装oracle扩展
			参考网址: http://blog.csdn.net/a82168506/article/details/11763989 步骤如下: 下载安装包,下载地址.(我下载的11.1版本) http://w ... 
- H5C3--过渡transition
			<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ... 
- 访问树中的所有元素(DOM)
			创建一个函数,给定页面上的DOM元素,将访问元素本身及其所有后代(而不仅仅是它的直接子代).对于访问的每个元素,函数应将该元素传递给提供的回调函数. 函数的参数应该是: 一个DOM元素 一个回调函数( ... 
- 安装 TortoiseSVN 时提示 please install the universal crt first
			win7x64 解决办法 去https://www.microsoft.com/zh-cn/搜索 universal crt (hotfix kb2999226)点击下图链接 也就是https://s ... 
- fidder抓包使用(一)
			fidder是会占用 jupyter 端口的,在fidder里边最上边找到tools--->options-->connections里边的8888改成别的重启jupyter就好了 
- spark应用程序引用别的jar包
			第一种方式 操作:将第三方jar文件打包到最终形成的spark应用程序jar文件中 应用场景:第三方jar文件比较小,应用的地方比较少 第二种方式 操作:使用spark-submit提交命令的参数: ... 
- Thinkphp 调试方法
			1.入口文件index.php配置APP_DEBUG,能直接发现页面上的错误 define('APP_DEBUG',True); 2.配置页面调试SHOW_PAGE_TRACE,可以在config里面 ... 
