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 }
时间: 2024-10-01 05:25:07