E. Present for Vitalik the Philatelist 反演+容斥

Posted acjiumeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了E. Present for Vitalik the Philatelist 反演+容斥相关的知识,希望对你有一定的参考价值。

题意:给n个数\(a_i\),求选一个数x和一个集合S不重合,gcd(S)!=1,gcd(S,x)==1的方案数.
题解:\(ans=\sum_i=2^nf_ig_i\),\(f_i\)是数组中和i的gcd不为1的个数,\(g_i\)是选取集合gcd为i的方案数.
\(f_n=\sum_i=1^N[gcd(n,i)!=1]a_i\)
\(f_n=\sum_i=1^N\sum_d|gcd(i,n)\mu(d)a_i\)
\(f_n=\sum_d|n\mu(d)\sum_i=1^\fracNda_i*d\)
\(f\)可以\(nlogn\)预处理
\(g_i=2^b_i-1-\sum_i|xg(x)\),\(b_i\)是数组中是i倍数的数的个数,可以\(nlogn\)处理

//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize(4)
//#pragma GCC optimize("unroll-loops")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include<bits/stdc++.h>
//#include <bits/extc++.h>
#define fi first
#define se second
#define db double
#define mp make_pair
#define pb push_back
#define mt make_tuple
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define ld long double
//#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define sqr(x) ((x)*(x))
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
#define ull unsigned long long
#define bpc __builtin_popcount
#define base 1000000000000000000ll
#define fin freopen("a.txt","r",stdin)
#define fout freopen("a.txt","w",stdout)
#define fio ios::sync_with_stdio(false);cin.tie(0)
#define mr mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
inline ll gcd(ll a,ll b)return b?gcd(b,a%b):a;
inline void sub(ll &a,ll b)a-=b;if(a<0)a+=mod;
inline void add(ll &a,ll b)a+=b;if(a>=mod)a-=mod;
template<typename T>inline T const& MAX(T const &a,T const &b)return a>b?a:b;
template<typename T>inline T const& MIN(T const &a,T const &b)return a<b?a:b;
inline ll qp(ll a,ll b)ll ans=1;while(b)if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;return ans;
inline ll qp(ll a,ll b,ll c)ll ans=1;while(b)if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;return ans;

using namespace std;
//using namespace __gnu_pbds;

const ull ba=233;
const db eps=1e-5;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int N=10000000+10,maxn=500000+10,inf=0x3f3f3f3f;

struct FastIO 
    static const int S = 1e7;
    int wpos;
    char wbuf[S];
    FastIO() : wpos(0) 
    inline int xchar() 
        static char buf[S];
        static int len = 0, pos = 0;
        if (pos == len)
            pos = 0, len = fread(buf, 1, S, stdin);
        if (pos == len) exit(0);
        return buf[pos++];
    
    inline int xuint() 
        int c = xchar(), x = 0;
        while (c <= 32) c = xchar();
        for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
        return x;
    
    inline int xint()
    
        int s = 1, c = xchar(), x = 0;
        while (c <= 32) c = xchar();
        if (c == '-') s = -1, c = xchar();
        for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
        return x * s;
    
    inline void xstring(char *s)
    
        int c = xchar();
        while (c <= 32) c = xchar();
        for (; c > 32; c = xchar()) * s++ = c;
        *s = 0;
    
    inline void wchar(int x)
    
        if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0;
        wbuf[wpos++] = x;
    
    inline void wint(ll x)
    
        if (x < 0) wchar('-'), x = -x;
        char s[24];
        int n = 0;
        while (x || !n) s[n++] = '0' + x % 10, x /= 10;
        while (n--) wchar(s[n]);
        wchar('\n');
    
    inline void wstring(const char *s)
    
        while (*s) wchar(*s++);
    
    ~FastIO()
    
        if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;
    
 io;
int mi[maxn],b[N],c[N],a[N],mu[N];
int main()

    int n=io.xint(),ma=0;
    mi[0]=1;
    for(int i=1;i<=n;i++)
    
        int x=io.xint();
        b[x]++;ma=max(ma,x);
        mi[i]=(1ll*mi[i-1]<<1)%mod;
    
    mu[1]=1;
    for(int i=1;i<=ma;i++)
    
        for(int j=i<<1;j<=ma;j+=i)
            b[i]+=b[j],mu[j]-=mu[i];
        for(int j=i;j<=ma;j+=i)
            c[j]+=mu[i]*b[i];
    
    for(int i=ma;i;i--)
    
        a[i]+=mi[b[i]]-1+mod;
        if(a[i]>=mod)a[i]-=mod;
        for(int j=i<<1;j<=ma;j+=i)
        
            a[i]-=a[j];
            if(a[i]<0)a[i]+=mod;
        
    
    ll ans=0;
    for(int i=2;i<=ma;i++)if(c[i]&&a[i])add(ans,1ll*c[i]*a[i]%mod);
    io.wint(ans);
    return 0;

/********************
1
10000000
********************/

以上是关于E. Present for Vitalik the Philatelist 反演+容斥的主要内容,如果未能解决你的问题,请参考以下文章

CF585E:Present for Vitalik the Philatelist

Codeforces 585E. Present for Vitalik the Philatelist(容斥)

The 17th Zhejiang Provincial Contest E. Easy DP Problem(主席树)

codeforces 37 E. Trial for Chiefspfa

Educational Codeforces Round 41 (Rated for Div. 2) E. Tufurama

Attribute class invalid for tag present according to TLD