1439 互质对
2016-09-13 11:47
309 查看
1439 互质对
题目来源: CodeForces
基准时间限制:2 秒 空间限制:131072 KB
有n个数字,a[1],a[2],…,a
。有一个集合,刚开始集合为空。然后有一种操作每次向集合中加入一个数字或者删除一个数字。每次操作给出一个下标x(1 ≤ x ≤ n),如果a[x]已经在集合中,那么就删除a[x],否则就加入a[x]。
问每次操作之后集合中互质的数字有多少对。
注意,集合中可以有重复的数字,两个数字不同当且仅当他们的下标不同。
比如a[1]=a[2]=1。那么经过两次操作1,2之后,集合之后存在两个1,里面有一对互质。
Input
Output
Input示例
Output示例
题目来源: CodeForces
基准时间限制:2 秒 空间限制:131072 KB
有n个数字,a[1],a[2],…,a
。有一个集合,刚开始集合为空。然后有一种操作每次向集合中加入一个数字或者删除一个数字。每次操作给出一个下标x(1 ≤ x ≤ n),如果a[x]已经在集合中,那么就删除a[x],否则就加入a[x]。
问每次操作之后集合中互质的数字有多少对。
注意,集合中可以有重复的数字,两个数字不同当且仅当他们的下标不同。
比如a[1]=a[2]=1。那么经过两次操作1,2之后,集合之后存在两个1,里面有一对互质。
Input
单组测试数据。 第一行包含两个整数n 和 q (1 ≤ n, q ≤ 2 × 10^5)。表示数字的种类和查询数目。 第二行有n个以空格分开的整数a[1],a[2],…,a (1 ≤ a[i] ≤ 5 × 10^5),分别表示n个数字。 接下来q行,每行一个整数x(1 ≤ x ≤ n),表示每次操作的下标。
Output
对于每一个查询,输出当前集合中互质的数字有多少对。
Input示例
样例输入1 5 6 1 2 3 4 6 1 2 3 4 5 1 样例输入2 2 3 1 1 1 2 1
Output示例
样例输出1 0 1 3 5 6 2 样例输出2 0 1 0 思路:容斥原理;求容斥每个数与其他数不互质的对数,然后sum+总的再减去不互质的即可;
#include<stdio.h> #include<algorithm> #include<iostream> #include<stdlib.h> #include<queue> #include<string.h> #include<set> #include<map> #include<math.h> using namespace std; typedef long long LL; bool flag[600005]; LL cnt[600005]; int ff[600005]; bool prime[600005]; LL sum = 0; int b[20]; int bns[600005]; int ans[600000]; int n; void slove(int x,int v); int main(void) { int q; scanf("%d %d",&n,&q); memset(cnt,0,sizeof(cnt)); memset(flag,0,sizeof(flag)); int i,j;int cn = 0; for(i = 2; i < 1000; i++) { if(!prime[i]) { for(j = i; ((LL)i*(LL)j) <= 500000; j++) { prime[i*j] = true; } } } for(i = 2;i < 500000; i++) { if(!prime[i]) { ans[cn++] = i; } } for(i = 0;i < cn ;i++) { for(j = 1;ans[i]*j <= 500000;j++) { ff[ans[i]*j] = ans[i]; } } for(i = 0; i < n; i++) { int x; scanf("%d",&bns[i]); } n = 0; while(q--) { int x; scanf("%d",&x); int id = x; x = bns[x-1]; { slove(x,id); } printf("%lld\n",sum); } return 0; } void slove(int x,int v) { int fl = 0; if(flag[v]) { flag[v]=false; n--; sum-=n; fl = 1; } else { flag[v]=true; sum += n; n++; }//printf("%d\n",sum); int c = x; int cn = 0; while(c>1) { if(cn==0) { b[cn++] = ff[c]; } else if(b[cn-1]!=ff[c]) { b[cn++] = ff[c]; } c/=ff[c]; } if(fl) { int i ,j; for(i = 1; i < (1<<cn); i++) { int ac = 1; int t = 0; for(j = 0; j < cn; j++) { if(i&(1<<j)) { t++; ac*=b[j]; } } if(t%2) { cnt[ac]--; sum += cnt[ac]; } else { cnt[ac]--; sum -= cnt[ac]; } } } else { int i ,j; for(i = 1; i < (1<<cn); i++) { int ac = 1; int t = 0; for(j = 0; j < cn; j++) { if(i&(1<<j)) { t++; ac*=b[j]; } } if(t%2) { sum -= cnt[ac]; cnt[ac]++; } else { sum += cnt[ac]; cnt[ac]++; } } } }
相关文章推荐
- 51Nod 1439:互质对(用莫比乌斯来容斥)
- 51nod 1439:互质对 容斥原理
- 51nod 1439:互质对 容斥原理 深搜!!!
- 51node1439 互质对(容斥原理)
- 51Nod 1439 互质对 容斥原理
- 51 nod 1439 互质对(Moblus容斥)
- 51Nod-1439-互质对
- hdu 3501 Calculation 2 求所以小于n且与n不互质的数之和
- marcool 0200 互质二元组 数论
- 判断两数是否互质
- 【转AekdyCoin】求小于等于N的与N互质的数的和
- 题目1439:Least Common Multiple
- 【置换群】 HDOJ 1439 && POJ 1026 Cipher
- Hduoj1439【加密】
- 判断2个正整数是否互质
- HDU 4135-Co-prime(容斥求区间内与N互质的个数(队列||位运算))
- poj 2981 Strange Way to Express Integers (中国剩余定理不互质)
- 中国剩余定理算法详解(余数互质和不互质)
- 非互质的中国剩余定理模板(1573)
- 容斥原理 —— 求1~n有多少个数与k互质(二进制算法详细解释&模板)