码迷,mamicode.com
首页 > 其他好文 > 详细

51nod1439 互质对

时间:2017-09-20 23:31:46      阅读:401      评论:0      收藏:0      [点我收藏+]

标签:有一个   back   color   表示   限制   blog   i++   air   整数   

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,里面有一对互质。

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
题解:这题等价于求一个数和一系列数有几个互质。
我们先想不互质的,不互质的情况是什么,两个数有非1的质因子。
然后就是容斥原理对质因子求个数了。
技术分享
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<cstdlib>
 7 #include<vector>
 8 using namespace std;
 9 typedef long long ll;
10 typedef long double ld;
11 typedef pair<int,int> pr;
12 const double pi=acos(-1);
13 #define rep(i,a,n) for(int i=a;i<=n;i++)
14 #define per(i,n,a) for(int i=n;i>=a;i--)
15 #define Rep(i,u) for(int i=head[u];i;i=Next[i])
16 #define clr(a) memset(a,0,sizeof(a))
17 #define pb push_back
18 #define mp make_pair
19 #define fi first
20 #define sc second
21 #define pq priority_queue
22 #define pqb priority_queue <int, vector<int>, less<int> >
23 #define pqs priority_queue <int, vector<int>, greater<int> >
24 #define vec vector
25 ld eps=1e-9;
26 ll pp=1000000007;
27 ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
28 ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
29 void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
30 //void add(int x,int y,int z){ v[++e]=y; next[e]=head[x]; head[x]=e; cost[e]=z; }
31 int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1};
32 ll read(){ ll ans=0; char last= ,ch=getchar();
33 while(ch<0 || ch>9)last=ch,ch=getchar();
34 while(ch>=0 && ch<=9)ans=ans*10+ch-0,ch=getchar();
35 if(last==-)ans=-ans; return ans;
36 }
37 const int N=1000000;
38 ll ans;
39 int c[N],zs[N],p[N],f[N],a[N],nu,fl[N];
40 void solve(int i,int k,int f,int t){
41     if (i==0) {
42         if (t==-1) c[k]--;
43         ans+=f*c[k];
44         if (t==1) c[k]++;
45         return ;
46     }
47     solve(i-1,k,f,t);
48     solve(i-1,k*zs[i],-f,t);
49 }
50 int main(){
51     int n=read(),q=read(),need=sqrt(500000);
52     for (int i=1;i<=n;i++) a[i]=read();        
53     for (int i=2;i<=need;i++) {
54         if (!f[i]) p[++nu]=i;
55         for (int j=1;j<=nu && i*p[j]<=need;j++){
56             f[i*p[j]]=1;
57             if (i%p[j]==0) break;
58         }
59     } 
60     ans=0;
61     while (q--){
62         int x=read(),n=a[x],g=0;
63         for (int i=1;i<=nu;i++){
64             if (n==1) break;
65             if (n%p[i]==0){
66                 zs[++g]=p[i];
67                 while (n%p[i]==0) n/=p[i];
68             }
69         }
70         if (n>1) zs[++g]=n;
71         if (fl[x]) solve(g,1,-1,-1);
72         else solve(g,1,1,1);
73         fl[x]^=1;
74         printf("%lld\n",ans);
75     }
76     return 0;
77 } 
View Code

 

 
 
 

51nod1439 互质对

标签:有一个   back   color   表示   限制   blog   i++   air   整数   

原文地址:http://www.cnblogs.com/SXia/p/7565340.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!