1439 互质对

1439 互质对

题目来源: CodeForces

基准时间限制:2 秒 空间限制:131072 KB

有n个数字,a[1],a[2],…,a[n]。有一个集合,刚开始集合为空。然后有一种操作每次向集合中加入一个数字或者删除一个数字。每次操作给出一个下标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[n] (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+总的再减去不互质的即可;
  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<stdlib.h>
  5 #include<queue>
  6 #include<string.h>
  7 #include<set>
  8 #include<map>
  9 #include<math.h>
 10 using namespace std;
 11 typedef long long LL;
 12 bool flag[600005];
 13 LL cnt[600005];
 14 int ff[600005];
 15 bool prime[600005];
 16 LL sum = 0;
 17 int b[20];
 18 int bns[600005];
 19 int ans[600000];
 20 int n;
 21 void slove(int x,int v);
 22 int main(void)
 23 {
 24         int q;
 25         scanf("%d %d",&n,&q);
 26         memset(cnt,0,sizeof(cnt));
 27         memset(flag,0,sizeof(flag));
 28         int i,j;int cn = 0;
 29         for(i = 2; i < 1000; i++)
 30         {
 31                 if(!prime[i])
 32                 {
 33                         for(j = i; ((LL)i*(LL)j) <= 500000; j++)
 34                         {
 35                                 prime[i*j] = true;
 36                         }
 37                 }
 38         }
 39         for(i = 2;i < 500000; i++)
 40         {
 41             if(!prime[i])
 42             {
 43                 ans[cn++] = i;
 44             }
 45         }
 46         for(i = 0;i < cn ;i++)
 47         {
 48             for(j = 1;ans[i]*j <= 500000;j++)
 49             {
 50                 ff[ans[i]*j] = ans[i];
 51             }
 52         }
 53         for(i = 0; i < n; i++)
 54         {
 55                 int x;
 56                 scanf("%d",&bns[i]);
 57         }
 58         n = 0;
 59         while(q--)
 60         {
 61                 int x;
 62                 scanf("%d",&x);
 63                 int id = x;
 64                 x = bns[x-1];
 65                 {
 66                         slove(x,id);
 67                 }
 68                 printf("%lld\n",sum);
 69         }
 70         return 0;
 71 }
 72 void slove(int x,int v)
 73 {
 74         int fl = 0;
 75         if(flag[v])
 76         {
 77                 flag[v]=false;
 78                 n--;
 79                 sum-=n;
 80                 fl = 1;
 81         }
 82         else
 83         {
 84                 flag[v]=true;
 85                 sum += n;
 86                 n++;
 87         }//printf("%d\n",sum);
 88         int c = x;
 89         int cn = 0;
 90         while(c>1)
 91         {
 92                 if(cn==0)
 93                 {
 94                         b[cn++] = ff[c];
 95                 }
 96                 else if(b[cn-1]!=ff[c])
 97                 {
 98                         b[cn++] = ff[c];
 99                 }
100                 c/=ff[c];
101         }
102         if(fl)
103         {
104                 int i ,j;
105                 for(i = 1; i < (1<<cn); i++)
106                 {
107                         int ac = 1;
108                         int t = 0;
109                         for(j = 0; j < cn; j++)
110                         {
111                                 if(i&(1<<j))
112                                 {
113                                         t++;
114                                         ac*=b[j];
115                                 }
116                         }
117                         if(t%2)
118                         {
119                                 cnt[ac]--;
120                                 sum += cnt[ac];
121                         }
122                         else
123                         {
124                                 cnt[ac]--;
125                                 sum -= cnt[ac];
126                         }
127                 }
128         }
129         else
130         {
131                 int i ,j;
132                 for(i = 1; i < (1<<cn); i++)
133                 {
134                         int ac = 1;
135                         int t = 0;
136                         for(j = 0; j < cn; j++)
137                         {
138                                 if(i&(1<<j))
139                                 {
140                                         t++;
141                                         ac*=b[j];
142                                 }
143                         }
144                         if(t%2)
145                         {
146                                 sum -= cnt[ac];
147                                 cnt[ac]++;
148                         }
149                         else
150                         {
151                                 sum += cnt[ac];
152                                 cnt[ac]++;
153                         }
154                 }
155         }
156 }
 
时间: 2024-08-07 20:30:29

1439 互质对的相关文章

51 nod 1439 互质对(Moblus容斥)

1439 互质对 题目来源: CodeForces 基准时间限制:2 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 有n个数字,a[1],a[2],…,a[n].有一个集合,刚开始集合为空.然后有一种操作每次向集合中加入一个数字或者删除一个数字.每次操作给出一个下标x(1 ≤ x ≤ n),如果a[x]已经在集合中,那么就删除a[x],否则就加入a[x]. 问每次操作之后集合中互质的数字有多少对. 注意,集合中可以有重复的数字,两个数字不同当且仅当他们的下标不同. 比如a[

51nod1439 互质对

1439 互质对 基准时间限制:2 秒 空间限制:131072 KB 有n个数字,a[1],a[2],-,a[n].有一个集合,刚开始集合为空.然后有一种操作每次向集合中加入一个数字或者删除一个数字.每次操作给出一个下标x(1 ≤ x ≤ n),如果a[x]已经在集合中,那么就删除a[x],否则就加入a[x]. 问每次操作之后集合中互质的数字有多少对. 注意,集合中可以有重复的数字,两个数字不同当且仅当他们的下标不同. 比如a[1]=a[2]=1.那么经过两次操作1,2之后,集合之后存在两个1,

NYOJ154 聪明的小珂 【互质】

聪明的小珂 时间限制:1000 ms  |  内存限制:1000 KB 难度:3 描写叙述 小珂是一个爱美的女孩.她有n条新项链.标号从1到n.每一条项链在颜色上都会有一些区别,n条项链依次摆放,围成一个圈.小珂每次都会从上一次选择项链的位置開始数到第k条项链,把这条项链作为今天要带的项链,每次数的方向都是一致的.如今希望你帮小珂计算出一个最大的k,满足k<=n/2的同一时候,使得小珂在接下来的n天中将全部的项链都刚好带了一遍. 比如 n=7.取k=3 天数  项链编号 1           

互质 整除 同余

互质 当(a,b)=1时,称a.b互质(素) 性质: 1.已知(a,c)=1,若a|bc,则a|b:若a|b,c|b,则ac|b 2.p为素数,若p|ab,则p|a或p|b 3.[a,b]*(a,b)=ab 4.(a,b)=(a,b-ac)=(a-bc,b) 5.存在整数x.y,使得ax+by=(a,b) 6.m(a,b)=(ma,mb) 7.若a|m,b|m,则[a,b]|m 8.m[a,b]=[ma,mb] 整除 设a,b为整数,a≠0,若有一整数q,使得b=aq,则称a是b的因数,b为a的

Hello Kiki(中国剩余定理——不互质的情况)

Hello Kiki Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 247 Accepted Submission(s): 107   Problem Description One day I was shopping in the supermarket. There was a cashier counting coins serio

HDU5668 Circle 非互质中国剩余定理

分析:考虑对给定的出圈序列进行一次模拟,对于出圈的人我们显然可以由位置,编号等关系得到一个同余方程 一圈做下来我们就得到了n个同余方程 对每个方程用扩展欧几里得求解,最后找到最小可行解就是答案. 当然不要忘了判无解的情况. 有非常多选手似乎都是一眼标算然后写挂了,对此表示很遗憾,但是此题确实是比较容易写挂的... 注:中国剩余定理 解模线性方程组的时候 有两种情况 1:一种是模数是两辆互质的,这样的题可以用LRJ白书上的模板,俗称CRT1 2:模数存在不互质的,这样的需要用合并方程的做法,俗称C

(hdu step 7.2.2)GCD Again(欧拉函数的简单应用——求[1,n)中与n不互质的元素的个数)

题目: GCD Again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 125 Accepted Submission(s): 84   Problem Description Do you have spent some time to think and try to solve those unsolved problem afte

容斥原理 求M以内有多少个跟N是互质的

开始系统的学习容斥原理!通常我们求1-n中与n互质的数的个数都是用欧拉函数! 但如果n比较大或者是求1-m中与n互质的数的个数等等问题,要想时间效率高的话还是用容斥原理! 本题是求[a,b]中与n互质的数的个数,可以转换成求[1,b]中与n互质的数个数减去[1,a-1]与n互质的数的个数. #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define LL long

中国剩余定理 互质与非互质版本

中国剩余定理互质版 设m1,m2,m3,...,mk是两两互素的正整数,即gcd(mi,mj)=1,i!=j,i,j=1,2,3,...,k. 则同余方程组: x = a1 (mod n1) x = a2 (mod n2) ... x = ak (mod nk) 模[n1,n2,...nk]有唯一解,即在[n1,n2,...,nk]的意义下,存在唯一的x,满足: x = ai mod [n1,n2,...,nk], i=1,2,3,...,k. 解可以写为这种形式: x = sigma(ai*