codeforces 547C 容斥原理

原创 2015年07月08日 17:44:34
/*
题意:
第一行有两个数n,q表示由n个数,q次询问
第二行有n个数a1,a2.....
接下来q行表示询问,每行一个数i表示ai在集合中是否存在(集合最初是空的)如果存在把
这个去掉以后问剩下的数两两互质的数有多少个。若果不存在把这个数加入集合,问两两互
质的有多少个。
注意:如果判断这个数在集合中存在的标志是这个数是否存在且下标是否一致,如果数存在但
下标不一致也应该把这个数加入到集合里头


思路:声明一个数x如果它不存在y>1且y的平方不是x的因数它就是好数
x=p1的a1次方*p2的a2次方*.....f(x)=a1+a2+a3+...换句话说a1,a2,...他们的值不是0就是1
然后声明d(x)为一个所有的数都有一个因数为x的集合。如果前面的集合中两两互质的已经算出
来了为ans,那么在加一个数,该是多少呢。ans=ans+d(1)-d(p1)-d(p2)-...d(pn)+d(p1p2)+
d(p1p3)+...-d(p1p2p3)-d(p1p2p4)....
d(1)的值应该为前面出现数的个数
d(p1)的值应该为前面出现有因数为P1的数的个数




上面的步骤就是容斥
*/
#include<bits/stdc++.h>
using namespace std;
const int maxn = 500005;
int a[200005],mul[80],cnt[maxn],has[200005];
vector<int> p[maxn];
long long ans;
void add(int val,int sign)
{
    for(int mask=0;mask<(1<<p[val].size());mask++)
    {
        if(!mask)
            mul[mask]=1;
        else
            mul[mask]=mul[mask&(mask-1)]*p[val][__builtin_ctz(mask)];
        if(sign<0)
            cnt[mul[mask]]--;
        if(__builtin_popcount(mask)&1)
            ans-=cnt[mul[mask]]*sign;
        else
            ans+=cnt[mul[mask]]*sign;
        if(sign>0)
            cnt[mul[mask]]++;
    }
}
int main()
{
    ios::sync_with_stdio(false);
    for(int i=2;i<maxn;i++)
        if(p[i].empty())
            for(int j=i;j<maxn;j+=i)
                p[j].push_back(i);
    int n,q;
    cin >> n >> q;
    for(int i=0;i<n;i++)
    {
        cin >> a[i];
        has[i]=1;
    }
    while(q--)
    {
        int x;
        cin >> x;
        x--;
        add(a[x],has[x]);
        has[x]*=-1;
        cout << ans << "\n";
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

CodeForces 547E Mike and Friends [Fail树+树状数组]

给出N个串,M个询问,对于每个询问L,R,K,给出串L到串R的所有串中串K作为子串出现了几次。(Fail树写法)...
  • GrassTreeFlower
  • GrassTreeFlower
  • 2016年02月29日 09:42
  • 562

[codeforces 547 E][51nod1440]迈克打电话

Description给出n个字符串,这n个字符串的总长为L,定义函数call(i,j)表示第j个字符串在第i个字符串中出现的次数。 给出q次询问,每次询问给出l,r,k,求∑ri=lcall(i,...
  • alan_cty
  • alan_cty
  • 2017年10月14日 10:11
  • 148

[Codeforces547C]Mike and Foam(莫比乌斯反演+组合数学)

题目描述传送门题解设f(n)f(n)表示gcd为n的数对个数,F(n)F(n)表示gcd为n的倍数的数对个数 那么F(n)=∑n|df(d)F(n)=\sum\limits_{n|d}f(d) 实...
  • Clove_unique
  • Clove_unique
  • 2017年03月21日 23:02
  • 531

【容斥原理】Codeforces547C[Mike and Foam]题解

题目概述给出一个序列 {An}\{A_n\} 和 mm 个操作,每个操作是一个整数 xx :如果 AxA_x 没有加入到容器中,则加入;如果 AxA_x 已经在容器中,则移除。求每次操作后容器中 gc...
  • zzkksunboy
  • zzkksunboy
  • 2017年08月22日 21:14
  • 251

“容斥原理及其应用”笔记

容斥原理 举例 对{1, 2, … , n}的排列i1, i2, … , in计数,其中1不在第1个位置上(即i1 ≠ 1) 已知1在第一个位置上的排列数和{2, 3, … , n}的排列数(n...
  • ArrowLLL
  • ArrowLLL
  • 2016年08月30日 23:43
  • 836

容斥原理专题一

抱歉,很久没有更新博客了。这几天集中刷了容斥原理的题目,于是就来写博客巩固下。容斥原理,我想大家在高中都或多或少的学过。虽然知道原理内容,但是用来解题的话,还是有点小障碍的,特别是不知道怎么写代码。如...
  • shengtao96
  • shengtao96
  • 2016年09月08日 21:33
  • 1180

容斥原理详解

翻译:vici@cust 对容斥原理的描述 容斥原理是一种重要的组合数学方法,可以让你求解任意大小的集合,或者计算复合事件的概率。 描述        容斥原理可以描述如下:  ...
  • usher_ou
  • usher_ou
  • 2017年03月31日 17:27
  • 743

容斥原理【模板】

容斥原理:在计数时,必须注意无一重复,无一遗漏。为了使重叠部分不被重复计算,人们研究出一种新的计数方法,这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计...
  • u011676797
  • u011676797
  • 2015年05月07日 19:49
  • 1188

【CF 140E】New Year Garland(第二类斯特林(Stirling)数+DP+容斥)

【CF 140E】New Year Garland(第二类斯特林(Stirling)数+DP+容斥) E. New Year Garlandtime limit per test5 secondsme...
  • ChallengerRumble
  • ChallengerRumble
  • 2016年08月08日 14:45
  • 686

ACM 容斥原理

VJ 点击打开链接 参考 点击打开链接  非常好的译文:点击打开链接 容斥原理的想法就是求多个集合的并集.所以要先设计好集合. 组合数学问题中,正面解决会困难,常用方法是正难则反,使用容斥原理求反向...
  • gg_gogoing
  • gg_gogoing
  • 2015年02月08日 08:57
  • 3517
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:codeforces 547C 容斥原理
举报原因:
原因补充:

(最多只允许输入30个字)