codeforces 547C 容斥原理

/*

题意:

第一行有两个数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;
}

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

时间: 2024-10-07 02:35:14

codeforces 547C 容斥原理的相关文章

Codeforces 547C Mike and Foam 容斥

题目链接:点击打开链接 题意: 给定n个数,q个操作 下面n个数 a1-an 开始有一个空的集合 每个操作一个数字 u (1<=u<=n) 表示把 a[u] 插入集合(若集合中没有a[u]), 否则就把a[u]从集合中删除 每个操作结束后输出 当前集合内有多少对数 是互质的. 思路: 分解质因素,然后容斥一下求 与a[u] 不互质的个数,做个差即可. PS: 在微软(苏州)bop现场和kuangbin,19891101 ,Jayye, xiaoxin等晚上一起在宾馆打的cf~ #include

Codeforces 839D Winter is here - 暴力 - 容斥原理

Winter is here at the North and the White Walkers are close. John Snow has an army consisting of n soldiers. While the rest of the world is fighting for the Iron Throne, he is going to get ready for the attack of the White Walkers. He has created a m

Codeforces Round #258 (Div. 2)Devu and Flowers 容斥原理

题目:Codeforces Round #258 (Div. 2)Devu and Flowers 题意:n个boxes ,第i个box有fi个flowers,每个boxes中的flowers完全相同,不同boxes的flowers不同,求从n个boxes中取出s个flowers的方案数.n<=20,s<=1e14,fi<=1e12. 排列组合的题目,一解法可用容斥原理(inclusion exclusion principle) . 有2中写法dfs和集合.下为集合写法. #inclu

Codeforces 451E Devu and Flowers(容斥原理)

题目链接:Codeforces 451E Devu and Flowers 题目大意:有n个花坛.要选s支花,每一个花坛有f[i]支花.同一个花坛的花颜色同样,不同花坛的花颜色不同,问说能够有多少种组合. 解题思路:2n的状态,枚举说那些花坛的花取超过了,剩下的用C(n?1sum+n?1)隔板法计算个数.注意奇数的位置要用减的.偶数的位置用加的.容斥原理. #include <cstdio> #include <cstring> #include <cmath> #in

[Codeforces 1228E]Another Filling the Grid (排列组合+容斥原理)

[Codeforces 1228E]Another Filling the Grid (排列组合+容斥原理) 题面 一个\(n \times n\)的格子,每个格子里可以填\([1,k]\)内的整数.要保证每行每列的格子上的数最小值为1,有多少种方案 \(n \leq 250,k \leq 10^9\) 分析 这题有\(O(n^3)\)的dp做法,但个人感觉不如\(O(n^2 \log n)\)直接用数学方法求更好理解. 考虑容斥原理,枚举有\(i\)行最小值>1,有\(j\)行最小值>1,那

Codeforces Round #258 E Devu and Flowers --容斥原理

这题又是容斥原理,最近各种做容斥原理啊.当然,好像题解给的不是容斥原理的方法,而是用到Lucas定理好像.这里只讲容斥的做法. 题意:从n个容器中总共取s朵花出来,问有多少种情况.其中告诉你每个盒子中有多少朵花. 分析:其实就是求方程: x1+x2+...+xn = s 的整数解的个数,方程满足: 0<=x1<=a[1], 0<=x2<=a[2]... 设:A1 = {x1 >= a[1]+1} , A2 = {x2 >= a[2]+1} , .... , An = {

Codeforces 839D Winter is here(容斥原理)

[题目链接] http://codeforces.com/contest/839/problem/D [题目大意] 给出一些数,求取出一些数,当他们的GCD大于0时,将数量乘GCD累加到答案上, 求累加和. [题解] 我们枚举GCD,统计为其倍数的数字数量,先假定其能组成的集合数为贡献, 但是我们发现在统计的过程中有多余统计的部分,比如4和8是2的倍数, 然而它们的GCD等于4,所以我们对于每个集合数的贡献要减去所有其倍数的集合数的贡献, 倒着容斥即可. [代码] #include <cstdi

Codeforces Round #428 (Div. 2) D. Winter is here[数论II][容斥原理]

传送门:http://codeforces.com/contest/839/problem/D Examples input 33 3 1 output 12 input 42 3 4 6 output 39 Note In the first sample the clans are {1},?{2},?{1,?2} so the answer will be 1·3?+?1·3?+?2·3?=?12 题解:当有n个数为x的倍数时 gcd为x对答案的贡献为$1*C_n^1+2*C_n^2+..

Codeforces 1245F. Daniel and Spring Cleaning(容斥原理+数位DP)

传送门 题目大意 给你两个数,\(l,r\) 求 \([l,r]\) 中多少对 \(a+b=a\oplus b\). 思路 看了大佬的题解才知道这里要用到二维容斥. 设 \(f_{x,y}\) 是 \(a\in [0,x],b\in [0,y]\) 时满足条件的对数 那么根据容斥原理答案就是 \(f_{r,r}-f_{l-1,r}\times 2+f_{l-1,l-1}\) 对于其中每一部分都可以用一次数位DP求出来 因为这里对于统计有影响的因素只有两个数是否被限制 那么状态可以直接设计为 \(