Codeforces Round #497 (Div. 2) D. Pave the Parallelepiped
阿新 • • 發佈:2018-12-09
連結
大意
給你(A,B,C)(A,B,C),求無序三元組(a,b,c)(a,b,c)使得a|A,b|B,c|Ca|A,b|B,c|C,一共TT組資料,T,A,B,C≤105
題解:
這個和容斥原理有關,程式碼很簡單,就是想不到方法!!!
#include<cstdio> #include<cstring> #include<iostream> #define N 100009 using namespace std; typedef long long ll; int fac[N]; int s[10]; int gcd (int a,int b) { if(b==0) return a; return gcd(b,a%b); } void fac_make() { for(int i=1;i<=N;i++) { for(int j=i;j<=N;j+=i) { fac[j]++; } } } int ok(int a,int b,int c){ if((a&1) && (b&2) && (c&4)) return 1; if((a&1) && (c&2) && (b&4)) return 1; if((b&1) && (a&2) && (c&4)) return 1; if((b&1) && (c&2) && (a&4)) return 1; if((c&1) && (a&2) && (b&4)) return 1; if((c&1) && (b&2) && (a&4)) return 1; return 0; } ll cn(int m,int n) { ll s=1; for(int i=0;i<n;i++) { s*=(m-i); s/=(i+1); } return s; } int main() { int t,a,b,c; //FILE *fp=fopen("t.txt","r"); int p[15]; memset(fac,0,sizeof(fac)); scanf("%d",&t); fac_make(); while(t--) { // cout<<t<<"****"<<endl; scanf("%d%d%d",&a,&b,&c); //cout<<a<<" "<<b<<" "<<c<<endl; int ab=gcd(a,b); int bc=gcd(b,c); int ac=gcd(a,c); int abc=gcd(ab,c); s[1]=fac[a]-fac[ab]-fac[ac]+fac[abc];//001 s[2]=fac[b]-fac[ab]-fac[bc]+fac[abc];//010 s[4]=fac[c]-fac[bc]-fac[ac]+fac[abc];//100 s[3]=fac[ab]-fac[abc];//011 s[6]=fac[bc]-fac[abc];//110 s[5]=fac[ac]-fac[abc];//101 s[7]=fac[abc]; /*for(int i=1;i<=7;i++) cout<<s[i]<<" "; cout<<endl;*/ ll ans=0; for(int i=1;i<8;i++) { for(int j=i;j<8;j++) { for(int k=j;k<8;k++) { if(ok(i,j,k)) { ll tp=1; memset(p,0,sizeof(p)); p[i]++;p[j]++;p[k]++; //cout<<i<<" "<<j<<" "<<k<<endl; for(int g=1;g<8;g++) if(p[g]>0) { tp*=cn(s[g]+p[g]-1,p[g]); //cout<<tp<<endl; } if(tp>0) ans+=tp; //printf("ans=%lld\n",ans); } } } } printf("%lld\n",ans); } return 0; }