zoukankan      html  css  js  c++  java
  • 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,里面有一对互质。

    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
    ",ans);
    75     }
    76     return 0;
    77 } 
    View Code
     
     
     
  • 相关阅读:
    Innodb中自增长值的列
    LINUX-vmstat命令讲解
    find命令总结
    特殊权限chattr的用法
    openstack的最简单安装
    解决新电脑的系统安装问题:针对BIOS的UEFI模式
    Linux中安装字体
    云主机和vps的区别
    install-scp
    常见typedef 用法
  • 原文地址:https://www.cnblogs.com/SXia/p/7565340.html
Copyright © 2011-2022 走看看