hdu5072 容斥定理求与一个数不互质的个数,然后化为求问题的反面

 1 #include<stdio.h>
 2 #include<string.h>
 3 int x,t[100005],d[100005];
 4 int f[100005][10],a[100005];
 5 int vis[355],prime[355];
 6 void dfs1(int tt,int now,int bei)
 7 {
 8      d[bei]++;
 9      for (int i=now+1;i<=t[tt];i++)
10          dfs1(tt,i,f[tt][i]*bei);
11  }
12   void dfs2(int tt,int now,int flag,int bei)
13  {
14      if (flag) x+=d[bei];
15      else x-=d[bei];
16      for (int i=now+1;i<=t[tt];i++)
17          dfs2(tt,i,1-flag,f[tt][i]*bei);
18 }
19 int main()
20 {
21     int cnt=0,i,j,T,n,y;
22     long long ans;
23     memset(vis,0,sizeof(vis));
24     for (i=2;i<=320;i++)
25     if (vis[i]==0){
26         cnt++;
27         prime[cnt]=i;
28         for (j=2;i*j<=320;j++) vis[i*j]=1;
29     }
30     scanf("%d",&T);
31     while (T--)
32     {
33         scanf("%d",&n);
34         for (i=1;i<=n;i++) scanf("%d",&a[i]);
35         memset(d,0,sizeof(d));
36         for (i=1;i<=n;i++)
37         {
38             x=a[i]; t[i]=0;
39             for (j=1;j<=cnt;j++)
40             {
41                 if (prime[j]>x) break;
42                 if (x%prime[j]==0) {t[i]++; f[i][t[i]]=prime[j]; }
43                 while (x%prime[j]==0) x/=prime[j];
44             }
45             if (x>1) {t[i]++; f[i][t[i]]=x; }
46             for (j=1;j<=t[i];j++) dfs1(i,j,f[i][j]);
47         }
48         ans=0;
49         for (i=1;i<=n;i++)
50         {
51             x=y=0;
52             for (j=1;j<=t[i];j++) dfs2(i,j,1,f[i][j]);
53             if (a[i]==1) x=0; else x--;
54             y=n-1-x;
55             ans=ans+(long long)x*(long long)y;
56          //printf("%d %d %d\n",x,y,ans);
57         }
58         ans=(long long)n*(long long)(n-1)*(long long)(n-2)/6-ans/2;
59         printf("%I64d\n",ans);
60     }
61 }

http://acm.hdu.edu.cn/showproblem.php?pid=5072

posted on 2014-10-22 23:07  xiao_xin  阅读(156)  评论(0编辑  收藏  举报

导航