• 【JZOJ3318】【LOJ2685】Brunhilda 的生日【数论,数学】


    题目大意:

    题目链接:https://loj.ac/problem/2685
    在这里插入图片描述


    思路:

    显然离线。
    f[x]f[x]表示人数为xx时的答案。可以证明f[x]f[x]为单调递增的。
    对于一个答案相同的区间[x,y][x,y],设xx的在给定集合里的最大质因子为pp,则显然xx+p1xsim x+p-1的答案与xx相同。因为gcd(x+p,x)=pgcd(x+p,x)=p,所以ans[x+p]=ans[x]+1ans[x+p]=ans[x]+1,然后ans[x]ans[x+p1]<ans[x+p]ans[x]leq ans[x+p-1]<ans[x+p]
    所以预处理出关于每一个xxpp(复杂度O(maxnloglogn)O(maxnlog log n)),然后就可以O(m)O(m)直接回答了。


    代码:

    #include <queue>
    #include <cstdio>
    #include <string>
    using namespace std;
    
    const int N=10000010;
    int n,m,x,maxn,p[N],v[N],ask[N],ans[N];
    queue<int> q;
    
    int read()
    {
    	int d=0;
    	char ch=getchar();
    	while (!isdigit(ch)) ch=getchar();
    	while (isdigit(ch))
    		d=(d<<3)+(d<<1)+ch-48,ch=getchar();
    	return d;
    }
    
    int main()
    {
    	n=read(); m=read();
    	for (int i=1;i<=n;i++)
    		p[i]=read();
    	for (int i=1;i<=m;i++)
    	{
    		ask[i]=read();
    		if (ask[i]>maxn) maxn=ask[i];
    	}
    	for (int i=1;i<=n;i++)
    		for (int j=p[i];j<=maxn;j+=p[i])
    			v[j]=p[i];
    	v[0]=p[n];
    	q.push(0);
    	for (int i=1;q.size()&&i<=maxn;)
    	{
    		x=q.front();
    		q.pop();
    		if (v[x])
    			for (;i<x+v[x] && i<=maxn;i++)
    			{
    				ans[i]=ans[x]+1;
    				q.push(i);
    			}
    	}
    	for (int i=1;i<=m;i++)
    		if (ans[ask[i]] || !ask[i]) printf("%d
    ",ans[ask[i]]);
    			else printf("oo
    ");
    	return 0;
    }
    
    
  • 相关阅读:
    [bzoj1089] 严格n元树
    [bzoj1097] 旅游景点atr
    [hdu3887] Counting Offspring
    [POJ3321] Apple Tree
    [POJ3635] Full Tank?
    git
    【MySQL】数据的导出导入
    Ubuntu python 开发环境配置
    测试markdown
    约瑟夫环问题-java实现
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998103.html
Copyright © 2020-2023  润新知