zoukankan      html  css  js  c++  java
  • 【20181027T1】洛阳怀【推结论+线性筛+分解质因数+GCD性质】

    原题:CF402D

    【错解】

    唔,先打个表看看

    咦,没有坏质数好像就是质因数个数啊

    那有坏质数呢?

    好像变负数了

    推出错误结论:f(x)=x的质因数个数,如果有个坏质数,就乘上-1

    然后乱搞,起码花了2个小时

    【正解】

    用脚趾头想一想都知道怎么可能长这样的?

    如果最小质因数是坏的,就去掉-1;否则去掉+1

    即好质因数-坏质因数

    开个bitset记坏质数,然后先筛一下,计算的时候分解(sqrt{1e9})质因数就好

    对于GCD:因为g[i]%g[i+1]==0,所以后面的操作对前面没有影响

    所以预处理前缀GCD,然后从后往前算f,如果<0就除一下

    另外:分解质因数应先筛出质数,然后枚举(sqrt{X})内的质数,一个个分解,最后如果X不为1再把自己加上

    复杂度(O(sqrt{max(A_i)}+frac{Nsqrt{N}}{log sqrt{N}}))

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    #include <bitset>
    #define MAXN 2005
    #define MAX 1000000
    using namespace std;
    typedef long long ll;
    bitset<1000000005> S;
    inline int read()
    {
    	int ans=0,f=1;
    	char c=getchar();
    	while (!isdigit(c))
    	{
    		if (c=='-') f=-1;
    		c=getchar();
    	}
    	while (isdigit(c))
    		ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return f*ans;
    }
    int n,m;
    bool np[MAX+5];
    int pl[MAX+5],cnt;
    void init()
    {
    	np[1]=1;
    	for (int i=2;i<=MAX;i++)
    	{
    		if (!np[i])
    			pl[++cnt]=i;
    		for (int j=1;j<=cnt&&i*pl[j]<=MAX;j++)
    		{
    			np[i*pl[j]]=1;
    			if (i%pl[j]==0) break;
    		}
    	}
    }
    int calc(int x)
    {
    	if (x==1) return 0;
    	int ans=0;
    	bool flag=false;
    	for (int i=1;i<=cnt&&pl[i]*pl[i]<=x;i++)
    		while (x%pl[i]==0)
    		{
    			ans+=(S[pl[i]]? -1:1);                          			
    			x/=pl[i];
    		}
    	if(x!=1)ans+=(S[x]? -1:1);
    	return ans;
    }
    int a[MAXN],b[MAXN];
    int gcd(int a,int b)
    {
    	return b? gcd(b,a%b):a;
    }
    int g[MAXN];
    int main()
    {
    	n=read(),m=read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	for (int i=1;i<=m;i++) S[read()]=1;
    	init();
    	for (int i=1;i<=n;i++) g[i]=gcd(g[i-1],a[i]);
    	ll ans=0;
    	for (int i=1;i<=n;i++) ans+=calc(a[i]);
    	int lazy=1;
    	for (int i=n;i>=1;i--) 
    	{
    		g[i]/=lazy;
    		int t=calc(g[i]);
    		if (t<0)
    		{
    			ans-=(ll)t*i;
    			lazy*=g[i];
    		}
    	}
    	cout<<ans;
    	return 0;
    }
    
  • 相关阅读:
    Trusted_Connection
    自定义绑定表达式
    【Android】Uri、UriMatcher、ContentUris详解
    Android事件传递机制【按键事件】
    ANDROID 9.PNG 图片制作
    Android ProGuard实例教程
    Android 几个Info系列类的总结
    NDK的讲义
    Android FrameWork——Touch事件派发过程详解
    【Android面试】Android面试题集锦 (陆续更新)
  • 原文地址:https://www.cnblogs.com/lstoi/p/9862184.html
Copyright © 2011-2022 走看看