hdu5072 Coprime (2014鞍山区域赛C题)(数论)
http://acm.hdu.edu.cn/showproblem.php?pid=5072
题意:给出N个数,求有多少个三元组,满足三个数全部两两互质或全部两两不互质。
题解:
http://dtyfc.com/acm/980 我看的这个学会的……
可以先求不满足要求的三元组数量,也就是abc,a和b互质,b和c不互质。
这样就要找这n个数中,和某个数不互质的数的个数。
可以质因数分解+容斥原理,求出和某个数不互质的数的个数(也就是和这个数有相同因数的数的个数)。
还要先预处理以某个数x为因子的数的个数,cnt[x]。
具体看代码。
其实我也不是很熟,醉了。
不信你看这个博客都没有数论分类
代码:
1 //#pragma comment(linker, "/STACK:102400000,102400000") 2 #include<cstdio> 3 #include<cmath> 4 #include<iostream> 5 #include<cstring> 6 #include<algorithm> 7 #include<cmath> 8 #include<map> 9 #include<set> 10 #include<stack> 11 #include<queue> 12 #include<ctime> 13 using namespace std; 14 #define mz(array) memset(array, 0, sizeof(array)) 15 #define mf1(array) memset(array, -1, sizeof(array)) 16 #define minf(array) memset(array, 0x3f, sizeof(array)) 17 #define REP(i,n) for(i=0;i<(n);i++) 18 #define FOR(i,x,n) for(i=(x);i<=(n);i++) 19 #define RD(x) scanf("%d",&x) 20 #define RD2(x,y) scanf("%d%d",&x,&y) 21 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z) 22 #define WN(x) printf("%d\n",x); 23 #define RE freopen("D.in","r",stdin) 24 #define WE freopen("huzhi.txt","w",stdout) 25 #define mp make_pair 26 #define pb push_back 27 #define pf push_front 28 #define ppf pop_front 29 #define ppb pop_back 30 typedef long long ll; 31 typedef unsigned long long ull; 32 33 const double pi=acos(-1.0); 34 const double eps=1e-10; 35 36 const int maxn=111111; 37 38 int a[maxn]; 39 int cnt[maxn]; 40 int n; 41 42 int b[maxn],bn; 43 44 int att,me; 45 inline void attack(const int &now,const int &sum,const int &flag) { 46 if(now==bn) { 47 if(sum==1)return; 48 // printf("sum=%d cnt[]=%d flag=%d\n",sum ,(cnt[sum]), flag); 49 att+=flag*(cnt[sum]); 50 return; 51 } 52 attack(now+1,sum,flag); 53 attack(now+1,sum*b[now],-flag); 54 } 55 56 57 ll farm() { 58 int i,j,k; 59 mz(cnt); 60 FOR(i,1,100000) 61 for(j=i; j<=100000; j+=i) 62 cnt[i]+=a[j]; 63 ll sm=0; 64 FOR(i,1,100000) { 65 if(a[i]) { 66 int s=(int)sqrt((double)i); 67 int t=i; 68 bn=0; 69 for(j=2; j<=s && t>1; j++){ 70 if(t%j==0){ 71 b[bn++]=j; 72 while(t%j==0)t/=j; 73 } 74 } 75 if(t>1)b[bn++]=t; 76 att=0; 77 me=i; 78 attack(0,1,-1); 79 // REP(j,bn)printf("%d,",b[j]); 80 // printf("(i=%d , att= %d re+=%d)\n",i,att,max(0 , att-1) * (n-att)); 81 sm+=(ll)max(0 , att-1) * (n-att); 82 } 83 } 84 return (ll)n*(n-1)*(n-2)/6 - sm/2; 85 } 86 87 88 int main() { 89 int T,i,x; 90 RD(T); 91 while(T--) { 92 RD(n); 93 mz(a); 94 REP(i,n) { 95 RD(x); 96 a[x]++; 97 } 98 printf("%I64d\n",farm()); 99 } 100 return 0; 101 }