• 【BZOJ5302】[HAOI2018]奇怪的背包(动态规划,容斥原理)


    【BZOJ5302】[HAOI2018]奇怪的背包(动态规划,容斥原理)

    题面

    BZOJ
    洛谷

    题解

    为啥泥萌做法和我都不一样啊
    一个重量为(V_i)的物品,可以放出所有(gcd(V_i,P))的重量,而多个物品也只要(gcd)就好了。
    现在的问题转变成了有多少个集合(S),满足(S+{P})中所有数的(gcd)(w)的因数。那么实际上就是直接令(a[i]'=gcd(a[i],P)),然后选出一个集合使得它是(gcd(P,w))的因数。
    考虑对于(P)的每个因数预处理答案,不记得在哪里看到的,当(P)较大的时候,其约数个数是(P^{frac{1}{3}})级别,那么在这里就可以暴力把所有因数算出来之后(O(sigma^2))计算,即先统计有多少个(a[i]')是当前(d)的倍数,那么贡献是(2^{s}-1),然后容斥减去所有(d)的倍数的答案就是(gcd)(d)的答案。然后再(O(sigma^2))的计算约数和就好了。
    这样子复杂度大概是(O((n+Q)logP+sigma(P)^2)),前面那个(log)来自于(gcd)的复杂度。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define MOD 1000000007
    #define MAX 1000100
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    int n,Q,P,a[MAX],bin[MAX];
    const int blk=50000;
    int w[blk],tot,id1[blk],id2[blk],f[blk],s[blk];
    int ID(int x){return x<blk?id1[x]:id2[P/x];}
    int S[blk],top;
    int main()
    {
    	n=read();Q=read();P=read();
    	for(int i=1;i<=n;++i)a[i]=__gcd(read(),P);
    	bin[0]=1;for(int i=1;i<=n;++i)bin[i]=(bin[i-1]<<1)%MOD;
    	for(int i=1;i*i<=P;++i)
    		if(P%i==0)
    		{
    			w[++tot]=i;
    			if(P/i!=i)w[++tot]=P/i;
    		}
    	sort(&w[1],&w[tot+1]);
    	for(int i=1;i<=tot;++i)
    		if(w[i]<blk)id1[w[i]]=i;
    		else id2[P/w[i]]=i;
    	for(int i=1;i<=n;++i)s[ID(a[i])]+=1;
    	for(int i=tot;i;--i)
    	{
    		int cnt=0;top=0;
    		for(int j=i;j<=tot;++j)
    			if(w[j]%w[i]==0)S[++top]=j,cnt+=s[j];
    		f[i]=bin[cnt]-1;
    		for(int j=2;j<=top;++j)f[i]=(f[i]+MOD-f[S[j]])%MOD;
    	}
    	for(int i=tot;i;--i)
    		for(int j=1;j<i;++j)
    			if(w[i]%w[j]==0)f[i]=(f[i]+f[j])%MOD;
    	while(Q--)
    	{
    		int d=__gcd(read(),P);
    		printf("%d
    ",f[ID(d)]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    使用python3自带工具2to3.py 转换 python2.x 代码 到python3
    python2代码转换python3(2018新)
    解析搜狗词库(python)
    把搜狗输入法词库导入Google拼音输入法
    QT 窗体控件的透明度设置(三种方法)
    Telnet协议详解(远程登陆协议)
    C++游戏开发需要阅读的书籍
    explicit的作用
    C#7.0
    ES6-2
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10410530.html
Copyright © 2020-2023  润新知