zoukankan      html  css  js  c++  java
  • 【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;
    }
    
  • 相关阅读:
    创意吃鱼法
    雅礼上课
    坏掉的项链Broken Necklace
    2018-04-02练习
    【11月12日】Hadoop架构
    【11月10日】Redis 主从复制技术
    【11月10日】Redis 缓存系统常见问题及解决方案
    【11月9日】Redis 持久化
    【11月7日】Redis核心对象和数据类型
    【11月7日】Redis简介
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10410530.html
Copyright © 2011-2022 走看看