zoukankan      html  css  js  c++  java
  • Gym-102576A Bags of Candies

    题目传送门

    分析:
    我们先找一下一定不能匹配的数有哪些,显然是(1)与在区间((lfloorfrac{N}{2} floor,N])的质数
    剩下的数能不能全部匹配呢?我们尝试构造一下
    把每个数分到其最大质因数的组中,对于每个质因数组,如果大小为偶数,那么就在内部全部匹配了
    如果大小为奇数,由于其最大质因数(p)一定不大于(lfloorfrac{N}{2} floor),那么一定存在(2p)不大于(N)
    (2p)这个数分到质因数(2)这个组中,进行匹配就好了
    假设一定不能匹配的数有(D)个,答案即为(lfloorfrac{N-D+1}{2} floor+D)
    求一个大区间的质数个数直接使用Min_25筛
    你高兴地敲完代码,往CF一交,发现TLE???
    不是很懂。。
    学习大佬代码之后发现预处理质数的倒数,把除法变成乘法直接快3倍???
    然后语言选C++17就可以过???
    不是很懂,这波真的不是很懂2333

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<iostream>
    #include<map>
    #include<string>
    
    #define maxn 1000005
    #define INF 0x3f3f3f3f
    #define eps 1e-8
    
    using namespace std;
    
    inline long long getint()
    {
        long long num=0,flag=1;char c;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
        while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
        return num*flag;
    }
    
    long long N,S;
    int pri[maxn],np[maxn],cnt;
    long long G0[maxn];
    long long num[maxn],tot;
    int pos1[maxn],pos2[maxn];
    double inv[maxn];
    
    inline void init()
    {
    	for(int i=2;i<maxn;i++)
    	{
    		if(!np[i])pri[++cnt]=i,inv[cnt]=1.0/pri[cnt];
    		for(int j=1;j<=cnt&&i*pri[j]<maxn;j++)
    		{
    			np[i*pri[j]]=1;
    			if(i%pri[j]==0)break;
    		}
    	}
    }
    
    inline int ID(long long x){return x<=S?pos1[x]:pos2[N/x];}
    inline long long solve()
    {
    	S=sqrt(N);tot=0;
    	for(long long i=1;i<=N;i++)
    	{
    		i=N/(N/i),num[++tot]=N/i;
    		G0[tot]=(num[tot]-1);
    		if(num[tot]<=S)pos1[num[tot]]=tot;
    		else pos2[i]=tot;
    	}
    	for(int j=1;j<=cnt;j++)for(int i=1;i<=tot&&1ll*pri[j]*pri[j]<=num[i];i++)
    		G0[i]-=G0[ID(num[i]*inv[j]+eps)]-(j-1);
    	return G0[1]-G0[2];
    }
    
    int main()
    {
    	init();
    	int T=getint();
    	while(T--)
    	{
    		N=getint();
    		long long D=solve()+1;
    		printf("%lld
    ",(N-D+1)/2+D);
    	}
    }
    

  • 相关阅读:
    多线程
    Java命令行传参
    IO流
    集合
    Java基础语法
    常见的数据结构
    泛型
    java 集合重要概念 (Set 的存储内存解析)
    java 集合重要概念 (== 和 equals 解读)
    java 集合重要概念 (实现一个简单的斗地主)
  • 原文地址:https://www.cnblogs.com/Darknesses/p/13199018.html
Copyright © 2011-2022 走看看