CF 803 F Coprime Subsequences (容斥原理)

来源:互联网 发布:webservice java 实例 编辑:程序博客网 时间:2024/05/16 19:18

Description

给定一个序列,求有多少个子串(可以不连续)满足所有数的gcd为1

Solution

ansigcdi的子串个数,fi为数列中是i的倍数的数,则gcdi的倍数的子序列个数显然是2f(i)11,则:

ansi=d=1niμ(d)×(2f(id)1)

发现ansi还可以表示为:
ansi=2f(i)1d=2niansid

答案为ans1

Code

#include<bits/stdc++.h>using namespace std;#define For(i , j , k) for (register int i = (j) , i##_end_ = (k) ; i <= i##_end_ ; ++ i)#define Fordown(i , j , k) for (register int i = (j) , i##_end_ = (k) ; i >= i##_end_ ; -- i)#define Set(a , b) memset(a , b , sizeof(a))#define pb(a) push_back(a)#define mp(a, b) make_pair(a, b)#define ALL(a) (a).begin(), (a).end()#define SZ(a) ((int)(a).size())#define INF (0x3f3f3f3f)#define INF1 (2139062143)#define Mod (1000000007)typedef long long LL;template <typename T> inline bool chkmax(T &a , T b) { return a < b ? (a = b , 1) : 0; }template <typename T> inline bool chkmin(T &a , T b) { return b < a ? (a = b , 1) : 0; }int _ , __;char c_;inline int read(){    for (_ = 0 , __ = 1 , c_ = getchar() ; !isdigit(c_) ; c_ = getchar()) if (c_ == '-') __ = -1;    for ( ; isdigit(c_) ; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48);    return _ * __;}inline void File(){#ifndef ONLINE_JUDGE    freopen("divisor.in" , "r" , stdin);    freopen("divisor.out" , "w" , stdout);#endif}const int maxn = 1000003, maxm = 1000003;int n, m, a[maxn], cnt[maxm], ans[maxm], pow2[maxn];int num[13], cntt;inline void write(int x){    if (!x){        putchar('0'); return ;    }    cntt = 0;    do    {        num[++ cntt] = x % 10;        x /= 10;    }while (x);    Fordown(i, cntt, 1) putchar(num[i] + 48);}int main(){    File();    n = read();    pow2[0] = 1;    For(i, 1, n) {        a[i] = read(), ++ cnt[a[i]], pow2[i] = pow2[i - 1] << 1;        chkmax(m, a[i]);        if (pow2[i] >= Mod) pow2[i] -= Mod;    }    For(i, 1, m >> 1) for (register int j = 2 * i; j <= m; j += i) cnt[i] += cnt[j];    Fordown(i, m, 1) {        ans[i] = pow2[cnt[i]] - 1;        for (register int j = 2 * i; j <= m; j += i)        {            ans[i] -= ans[j];            if (ans[i] < 0) ans[i] += Mod;        }    }    write(ans[1]); putchar('\n');    return 0;}//雪花遣霰作前锋,势破张皇欲暗空。//筛瓦巧寻疏处漏,跳阶误到暖边融。//寒声带雨山难白,冷气侵人火失红。//方讶一冬暄较甚,今宵敢叹卧如弓。//--杨万里《霰》
原创粉丝点击