Code Forces 547 C. Mike and Foam(素因子分解+容斥)
来源:互联网 发布:芒果tv网络电视会员 编辑:程序博客网 时间:2024/05/16 03:34
Description
有n张牌,每张牌上都写着一个数字ai,开始时所有牌都在手上。现在有q个询问,每次询问指定一个数x,如果第x张牌在你手上,就要把它放在桌子上;如果在桌子上,就要拿回手中。每次这样拿完或者放完牌,要求回答当前桌子上的牌中,有多少对(i,j)(i < j),满足gcd(ai,aj)=1
Input
第一行为两个整数n和q表示牌的数量和查询数量,第二行n个整数表示每张牌上的数字,最后q行每行一个整数x表示查询
Output
对于每次查询,输出对第x张牌操作后桌子上的牌中,有多少i < j,满足gcd(ai,aj)=1
Sample Input
5 6
1 2 3 4 6
1
2
3
4
5
1
Sample Output
0
1
3
5
6
2
Solution
令ans为桌子上的牌中满足gcd(ai,aj)=1的(i,j)对数,num[i]记录桌上牌中以i为因子的牌的数量,tol记录桌上牌数
1.每在桌子上放一张牌x,ans增量为桌上原有牌中与x互素的牌的数量,那么枚举x的素因子,利用容斥原理可以求出桌上所有与x不互素的牌的数量sum,那么此时ans+=(tol-sum),tol++
2.每从桌上拿走一张牌,ans减量为拿走牌后桌上牌中与x互素的牌的数量,同样枚举x的素因子,利用容斥原理求出拿走牌后桌上所有与x不互素的牌的数量sum,那么此时tol–,ans-=(tol-sum)
Code
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;typedef long long ll;#define maxn 555555ll n,q,a[maxn];ll res,prime[maxn];ll tol,num[2*maxn];//tol记录桌上牌数,num[i]记录桌上以i为因子的牌数 ll ans;//ans记录答案值 bool vis[maxn];void get_prime(ll n)///对n素分解 { res=0; for(ll i=2;i*i<=n;i++) { if(n%i==0) { prime[res++]=i; while(n%i==0) n/=i; } } if(n!=1) prime[res++]=n;}void sub(ll n)//将第n张牌从桌子上拿走 { vis[n]=false;//取消标记 ll sum=0;//统计桌上原有牌中与n互素的牌数 for(ll i=1;i<(1<<res);i++)//容斥 { ll temp=1,ret=0; for(ll j=0;j<res;j++) if(i&(1<<j)) temp*=prime[j],ret++; num[temp]--;//以temp为因子的牌数减一 if(ret%2) sum+=num[temp]; else sum-=num[temp]; } tol--;//桌上牌数减一 ans-=(tol-sum); printf("%I64d\n",ans); return ;}void add(ll n)//将第n张牌放在桌子上 { vis[n]=true;//标记这张牌 ll sum=0;//统计桌上原有牌中与n互素的牌数 for(ll i=1;i<(1<<res);i++)//容斥 { int temp=1,ret=0; for(ll j=0;j<res;j++) if(i&(1<<j)) temp*=prime[j],ret++; if(ret%2) sum+=num[temp]; else sum-=num[temp]; num[temp]++;//以temp为因子的牌数加一 } ans+=(tol-sum); tol++;//桌上牌数加一 printf("%I64d\n",ans); return ;}int main(){ scanf("%I64d%I64d",&n,&q); for(ll i=1;i<=n;i++) scanf("%I64d",&a[i]); memset(vis,false,sizeof(false));//初始化 memset(num,0,sizeof(num));//初始化 tol=0; ans=0; while(q--) { ll x; scanf("%I64d",&x); get_prime(a[x]);//对第x张牌的数字素分解 if(vis[x])//x已经在桌上则将其拿走 sub(x); else//x不在桌上则将其放在桌上 add(x); } return 0;}
0 0
- Code Forces 547 C. Mike and Foam(素因子分解+容斥)
- CF 547 C Mike and Foam(容斥原理)
- Mike and Foam - CodeForces #547 C 容斥原理
- Codeforces 547C Mike and Foam 容斥
- codeforces/#305 Div1/547/C Mike and Foam 【容斥】
- 【Codeforces】547C Mike and Foam 容斥
- E. Mike and Foam(容斥原理)
- Codeforces 548E Mike and Foam(容斥)
- CodeForces 548E Mike and Foam (容斥+数论)
- codeforces548E Mike and Foam -- 容斥
- *Codeforces Round #305 (Div. 1) C. Mike and Foam(容斥原理)
- code forces 548C:Mike and frog
- codeforces 547C. Mike and Foam (反演)
- Codeforces Round #305 (Div. 1)C. Mike and Foam(素数+容斥)
- CF 305 div2 E. Mike and Foam (容斥原理)
- 【容斥原理】Codeforces547C[Mike and Foam]题解
- POJ 3904 Sky Code(素因子分解+容斥)
- Codeforces Round #305 (Div. 2) E. Mike and Foam 容斥原理
- C++ const的使用
- 单点CAS搭建服务端+客户端
- 通过javascript获取URL中的参数
- 密码验证合格程序
- [HDU 3966] Aragorn's Story 树链剖分
- Code Forces 547 C. Mike and Foam(素因子分解+容斥)
- 将页脚固定在页面底部
- Linux平台上SQLite数据库教程(一)——终端使用篇
- PEP8 Python 编码规范整理
- 3.2 电话号码对应的英语单词
- 函数 Func
- hdoj 1863 畅通工程【最小生成树,kruskal&&prim】
- hdu 1257 最少拦截系统(贪心)
- 工作日志