codeforces 1007B Pave the Parallelepiped

看了官方的题解才看懂的, 题解直通车,思路很巧妙

记录一下自己所学的新知识

get的新知识:从一个装有m个不同的球的袋子中有放回的取n次,选取的结果的不同状态有gcd(m+n-1,n)种

例:从含有3个球的袋子中有放回的选3次,结果状态有gcd(3+3-1,3)=gcd(5,3)=10种,分别为:
1,1,1
2,2,2
3,3,3
1,1,2
1,1,3
2,2,1
2,2,3
3,3,1
3,3,2
1,2,3

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<queue>
#include<vector>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<fstream>
#include<cstdlib>
#include<ctime>
using namespace std;
typedef long long ll;
typedef long long lint;
const ll mod=1e9+7;
const int maxn=1e5+7;
const int maxm=1e8+7;
const double eps=1e-4;

ll a,b,c;
int ds[maxn];

bool che(int a,int b,int c)
{
    if((a&1) && (b&2) && (c&4))return true;
    if((a&1) && (c&2) && (b&4))return true;
    if((b&1) && (a&2) && (c&4))return true;
    if((b&1) && (c&2) && (a&4))return true;
    if((c&1) && (b&2) && (a&4))return true;
    if((c&1) && (a&2) && (b&4))return true;
    return false;
}


int main()
{
    memset(ds,0,sizeof(ds));
    for(int i=1;i<maxn;i++){
        for(int j=i;j<maxn;j+=i)ds[j]++;
    }
    int t;scanf("%d",&t);
    while(t--){
        scanf("%I64d%I64d%I64d",&a,&b,&c);
        ll ab=ds[__gcd(a,b)],ac=ds[__gcd(a,c)],bc=ds[__gcd(c,b)];
        ll abc=ds[__gcd(a,__gcd(b,c))];
        ll ar[10];
        ar[7]=abc;
        ar[6]=ab-abc;
        ar[5]=ac-abc;
        ar[2]=ds[b]-ab-bc+abc;
        ar[3]=bc-abc;
        ar[4]=ds[a]-ab-ac+abc;
        ar[1]=ds[c]-ac-bc+abc;
        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(che(i,j,k)){
                        //if(ar[i]>0 && ar[j]>0 && ar[j]>0)cout<<i<<" "<<j<<" "<<k<<"\n";
                        if(i==j && j==k){
                            ll mid=ar[i];
                            ans += mid*(mid+1)*(mid+2)/6;
                        }
                        else if(i==j){
                            ans += ar[i]*(ar[i]+1)/2*ar[k];
                        }
                        else if(k==j){
                            ans += ar[j]*(ar[j]+1)/2*ar[i];
                        }
                        else if(i==k){
                            ans += ar[i]*(ar[i]+1)/2*ar[j];
                        }
                        else{
                            ans += ar[i]*ar[j]*ar[k];
                        }
                    }
                }
            }
        }
        printf("%I64d\n",ans);

    }
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/jfnfjivkdnfjf/article/details/81203495