51node1439 互质对(容斥原理)
2016-09-29 16:55
357 查看
51node1439
题目
中文题目思路
引用2997ms的话:“如果已知当前集合中互质的个数为ans,那么加入或者删除某个元素最后的结果也就是ans加上或减去该元素与集合中元素互质的个数。
所以要求的就是一个数与集合中各个数之间互质的个数。
做法是把每一个数拆成各个质数因子的乘积,然后对这些质数进行排列组合,那6来说,先假设将所有元素都是与6互质的,然后这里面减去因子有2的(与6一定不互质了),再减去因子有3的,但是这里面减的话,有部分减重复了,就是因子既有2又有3的,所以又要加上因子6的个数,使用容斥原理最终得到结果。”
代码
#include <iostream> #include <algorithm> #include <cmath> #include <vector> #include <string> #include <cstring> #include <cstdio> using namespace std; typedef long long ll; const int maxn=200010; const int maxm=500010; vector<int>prime[maxm]; int cnt[maxm],n,q,x; int val[maxn],vis[maxn]; void init() { for(int e=2; e<maxm; e++) { if(!prime[e].size()) for(int i=e; i<maxm; i+=e) { prime[i].push_back(e); } } } int cal(int n,int type) { int ans=0; for(ll mark=1; mark<(1<<prime .size()); mark++) { ll odd=0; ll mul=1; for(ll i=0; i<prime .size(); i++) { if(mark&(1<<i)) { odd++; mul*=prime [i]; } } if(odd&1) ans+=cnt[mul]; else ans-=cnt[mul]; cnt[mul]+=type; } return ans; } int main() { init(); scanf("%d %d",&n,&q); for(int i=1; i<=n; i++) scanf("%d",&val[i]); ll ans=0; int one=0; int now=0; for(int i=0; i<q; i++) { scanf("%d",&x); if(vis[x]==0) { vis[x]=1; if(val[x]==1) { ans+=one+now; one++; } else { ans+=one+(now-cal(val[x],1)); now++; } } else { vis[x]=0; if(val[x]==1) { ans-=(one-1)+now; one--; } else { ans-=one+(now-cal(val[x],-1)); now--; } } printf("%I64d\n",ans); } return 0; }
相关文章推荐
- 51nod 1439:互质对 容斥原理
- 51nod 1439:互质对 容斥原理 深搜!!!
- 51Nod 1439 互质对 容斥原理
- HDU 5768 Lucky7 容斥原理+中国剩余定理(互质)
- 51Nod-1439-互质对
- 容斥原理 —— 求1~n有多少个数与k互质(二进制算法详细解释&模板)
- 1439 互质对
- 求1~n与x互质的数的个数(6个题、容斥原理)
- Visible Trees + 数论,互质和容斥原理
- 51Nod 1439:互质对(用莫比乌斯来容斥)
- hdu 4135 容斥原理 求(1,m)区间与n互质的数的个数. 4000
- HDU 4135:Co-prime 容斥原理求(1,m)中与n互质的数的个数
- 【容斥原理-求区间内与n互质的数】HDOJ Co-prime 4135
- 51 nod 1439 互质对(Moblus容斥)
- 【转】求小于等于N的与N互质的数的和
- HDU/HDOJ 1573 X问题 非互质情况下的中国剩余定理
- 杭电2841 容斥定理求1到n之间和x互质的数的总数
- 【容斥原理】能量采集
- a^x%c的确定循环节起始位置(a和c不互质)
- hdu 2461 容斥原理 Rectangle