LG P6570 [NOI Online #3 提高组]优秀子序列

Description

给定一个长度为 $n$ 的非负整数序列 $A={a_1,a_2,cdots,a_n}$,对于 $A$ 的一个子序列 $B={a_{b_1},a_{b_2},cdots,a_{b_m}}$($0le mle n$,$1le b_1 < b_2 < cdots < b_mle n$,下同),称 $B$ 是 $A$ 的优秀子序列当且仅当,其任意两个不同元素的按位与结果均为 $0$,即:$forall 1le i < jle m$,满足:$a_{b_i}~mathrm{and}~a_{b_j}=0$,其中 $~mathrm{and}~$ 是按位与运算。

对于子序列 $B={a_{b_1},a_{b_2},cdots,a_{b_m}}$,我们定义其价值为 $varphi(1+sum_{i=1}^m a_{b_i})$,其中 $varphi(x)$ 表示小等于 $x$ 的正整数中与 $x$ 互质的数的个数。

现在请你求出 $A$ 的所有优秀子序列的价值之和,答案对 $10^9+7$ 取模。

Solution

如果将每个数视为$2$的幂次的集合,那么题目就是要求$sum_{x in S}x$,$S$是一个合法序列

因为$2$的幂次相加不会进位,上式就是$cup_{x in S}x$

设$dp_i$表示合法序列中所有元素并为$i$的方案数

那么题中所求即为

$$sum dp_x varphi(x+1)$$

$varphi$可以一次线性筛求出,$dp$可以一次子集DP求出

最后加上空集

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
long long n,maxx,tot,m;
long long dp[400005]={1},phi[400005],buc[400005],prime[400005],a[1000005],ans=1;
bool vst[400005];
const long long mod=1e9+7;
inline long long read()
{
    long long f=1,w=0;
    char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
    return f*w;
}
void pre(long long N)
{
    phi[1]=1;
    for(long long i=2;i<=N;i++)
    {
        if(!vst[i]) prime[++tot]=i,phi[i]=i-1;
        for(long long j=1;j<=tot&&i*prime[j]<=N;j++)
        {
            vst[i*prime[j]]=true;
            if(!(i%prime[j]))
            {
                phi[i*prime[j]]=phi[i]*prime[j];break;
            }
            else phi[i*prime[j]]=phi[i]*phi[prime[j]];
        }
    }
}
int main()
{
    n=read();
    for(long long i=1;i<=n;i++) a[i]=read(),maxx=max(maxx,a[i]),buc[a[i]]++;
    while((1<<m)<=maxx) m++;
    pre(1<<m);
    for(long long i=1;i<=(1<<m);i++)
    {
        for(long long s=i;;s=(s-1)&i)
        {
            long long t=i^s;
            if(s<t) break;
            (dp[i]+=dp[t]*buc[s]%mod)%=mod;
        }
        (ans+=dp[i]*phi[i+1]%mod)%=mod;
    }
    for(long long i=1;i<=buc[0];i++) (ans*=2)%=mod;
    printf("%lld
",ans);
    return 0;
}
优秀子序列
原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14052090.html