您的位置:首页 > 其它

容斥定理

2015-09-07 23:04 316 查看
Mark





神奇的TLE,把一个强转去掉就600+Ms过了….

//HDU 5072 直接容斥 莫比乌斯在后面
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>

using namespace std;

int n, a[100005], f[100005];

bool v[100005];

vector <int> q;

int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d", &T);
while(T--)
{
memset(f, 0, sizeof(f));
memset(v, false, sizeof(v));
scanf("%d", &n);
int maxx=-1;
for(int i = 0; i < n; ++i)
{
scanf("%d", a + i);
v[a[i]] = true;
maxx = max(maxx, a[i]);
}
for(int i = 2; i <= maxx; ++i)
{
for(int j = i; j <= maxx; j += i)
if(v[j])f[i]++;
}
long long ans = 0LL;
for(int i = 0; i < n; ++i)
{
//if(a[i] == 1)continue;
int now = a[i];
q.clear();
for(int j = 2; j <= now / j; ++j)
if(now % j == 0)
{
q.push_back(j);
while(now % j == 0)
{
now /= j;
}
}
if(now != 1)q.push_back(now);
int len = (int)q.size();
int b = 1 << len, cnt, fac;
long long r = 0LL;
for(int j = 1; j < b; ++j)
{
fac = 1;
cnt = 0;
for(int k = 0; k < len; ++k)
{
if((1 << k)&j)
{
cnt++;
fac *= q[k];
}
}
if(cnt & 1)r += f[fac];
else r -= f[fac];
}
if(r)r--;
ans += r * (n - 1 - r);
}
long long p = (long long)n * (n - 1) * (n - 2) / 6LL;
p-= ans / 2LL;
printf("%I64d\n",p);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: