zoukankan      html  css  js  c++  java
  • hdu 5072 Coprime(同色三角形+容斥)

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


    单色三角形模型


    现场赛和队友想了3个小时,最后发现想跑偏了。感觉好可惜的一道题,要是知道这个模型....就能够轻松的拿银了啊。

    题意不再赘述,就是求同色三角形的个数。总的三角形的个数是C(n,3),仅仅需减去不同色的三角形就可以。对于每一个点(数),与它互质的连红边,不互质的连蓝边,那么对于该点不同色三角形个数为蓝边数*红边数/2,由于同一个三角形被计算了两次。

    那么同色三角形个数为C(n,3) - ∑蓝边数*红边数/2。

    我们仅仅需求出蓝边数就能得知红边数。怎么求与该数不互质的数的个数?首先对原来的数质因子分解,把这些质因子的全部组合枚举出来,每一个质因子最多使用一次,得到若干个质因子的组合为ansNum,使用容斥原理,观察ansNum的质因子的个数。若是奇数就加上全部能被ansNum整数的数的个数。否则就减去。这样求出蓝边数。红边数也就已知了。


    #include <stdio.h>
    #include <iostream>
    #include <map>
    #include <set>
    #include <bitset>
    #include <list>
    #include <stack>
    #include <vector>
    #include <math.h>
    #include <string.h>
    #include <queue>
    #include <string>
    #include <stdlib.h>
    #include <algorithm>
    #define LL __int64
    //#define LL long long
    #define eps 1e-9
    #define PI acos(-1.0)
    using namespace std;
    const LL INF = 1<<30;
    const int maxn = 100010;
    
    int test;
    LL n;
    int a[maxn],num[maxn];
    int prime[maxn];
    bool flag[maxn];
    int fact[maxn][20];
    int coun[maxn];
    
    void getPrime()
    {
        memset(flag,0,sizeof(flag));
        flag[1] = true;
        prime[0] = 0;
        for(int i = 2; i < maxn; i++)
        {
            if(flag[i] == false)
                prime[++prime[0]] = i;
            for(int j = 1; j <= prime[0]&&i*prime[j] < maxn; j++)
            {
                flag[prime[j]*i] = true;
                if(i%prime[j] == 0)
                    break;
            }
        }
    }
    
    void getFact(int dig, int pos)
    {
    	int tmp = dig;
    
        for(int i = 1; i <= prime[0] && prime[i]*prime[i] <= tmp; i++)
        {
        	if(tmp % prime[i] == 0)
        	{
        		fact[pos][coun[pos]++] = prime[i];
        		while(tmp % prime[i] == 0)
    				tmp /= prime[i];
        	}
        	if(tmp == 1)
    			break;
        }
        if(tmp > 1)
    		fact[pos][coun[pos]++] = tmp;
    }
    
    void init()
    {
        for(int i = 2; i <= 100000; i++)
        {
            for(int j = i+i; j <= 100000; j += i)
                num[i] += num[j];
        }
    }
    
    
    int main()
    {
    	getPrime();
        scanf("%d",&test);
        while(test--)
        {
            memset(num,0,sizeof(num));
            scanf("%I64d",&n);
            for(int i = 1; i <= n; i++)
            {
                scanf("%d",&a[i]);
                num[a[i]]++;
            }
    
    		init();
    		memset(coun,0,sizeof(coun));
    
    		LL ans = 0;
    
    		for(int i = 1; i <= n; i++)
    		{
    			LL res = 0;
    			getFact(a[i], i);
    			for(int j = 1; j < (1<<coun[i]); j++)
    			{
    				LL ansNum = 1;
    				int cnt = 0;
    				for(int k = 0; k < coun[i]; k++)
    				{
    					if(j & (1<<k) )
    					{
    						ansNum *= fact[i][k];
    						cnt++;
    					}
    				}
    				if(cnt & 1)
    					res += (num[ansNum]-1);
    				else
    					res -= (num[ansNum]-1);
    			}
    			ans += (n-1-res)*res;
    		}
    		ans = n*(n-1)*(n-2)/6 - ans/2; //注意n为LL
    		printf("%I64d
    ",ans);
        }
        return 0;
    }
    
    
    



  • 相关阅读:
    Android AHandle AMessage
    android java 与C 通过 JNI双向通信
    android 系统给应用的jar
    UE4 unreliable 同步问题
    UE4 difference between servertravel and openlevel(多人游戏的关卡切换)
    UE4 Run On owing Client解析(RPC测试)
    UE4 TSubclassOf VS Native Pointer
    UE4 内容示例网络同步Learn
    UE4 多人FPS VR游戏制作笔记
    UE4 分层材质 Layerd Materials
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5062885.html
Copyright © 2011-2022 走看看