hdu4048
题意:给定m个数,还有n,n表示有一个长度为n的环,现在要求从M个数中选出若干个数,要求选出的数最大公约数为1,填充在n个位置中,选出的数可以重复,求多少种种方案。旋转当成一样的 。
思路:假设现在选出k个数,满足这k个数gcd为1,那么就是一个k种颜色给长度为n的环染色的问题,也就是经典的polya问题。
接着我们考虑如何使其gcd为1。。我们可以考虑下容斥原理。gcd为1统计一遍,然后减掉gcd为2和3的,gcd为6多减了再加回来,依次类推。大体就是这样。。
值得注意的时,答案要mod 10007,当 n为10007的时候无乘法逆元,就会出问题。所以做的时候要mod (10007 * n),最后答案再 / n. 至于为什么有这个公式。我也不大懂。求数论大神指教。。
下面就是代码:
/*
* Author: yzcstc
* Created Time: 2013/10/26 13:55:35
* File Name: hdu4048.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<utility>
#define M0(x) memset(x, 0, sizeof(x))
#define Inf 0x7fffffff
#define PB push_back
#define SZ(v) ((int)(v).size())
#define maxn 101001
#define maxm 20010
using namespace std;
int n, m, T, M;
int vis[maxm], tot, phi[maxn + ], flag[maxm], cnt[maxm], mm;
vector<int> fac[maxn]; void init(){
for (int i = ; i < maxm; i++) if (!vis[i]) {
flag[i] = ;
for (int j = i * ; j < maxm; j += i) {
if (!vis[j]) vis[j] = flag[j] = ;
else if (flag[j]) flag[j]++;
if (j%(i*i) == ) flag[j] = ;
}
} for (int i = ; i < maxm; ++i)
for (int j = ; j * j <= i; ++j)
if (i % j == ){
fac[i].push_back(j);
if (j * j < i) fac[i].push_back(i / j);
} for (int i = ; i < maxn; ++i) phi[i] = i;
for (int i = ; i < maxn; ++i)
if (phi[i] == i)
for (int j = i; j < maxn; j += i)
phi[j] = phi[j] / i * (i - );
} long long power(long long a, long long b){
long long ret = ;
while (b){
if (b & ) ret = ret * a % M;
a = a * a % M;
b >>= ;
}
return ret;
} long long cal(int l){
long long ret = power(cnt[], l);
for (int i = ; i <= mm; ++i){
if (flag[i] == ) continue;
if (flag[i] & ) ret = (ret - power(cnt[i], l)) % M;
else ret = (ret + power(cnt[i], l)) % M;
}
return ret < ? ret + M : ret;
} void solve(){
scanf("%d%d", &m, &n);
M = n * ;
long long ans = mm = ;
M0(cnt);
int x;
for (int i = ; i <= m; ++i){
scanf("%d", &x);
mm = max(x, mm);
for (int j = ; j < fac[x].size(); ++j)
cnt[fac[x][j]]++;
}
for (int i = ; i * i <= n; ++i)
if (n % i == ){
ans = (ans + cal(i) * phi[n / i]) % M;
if (i * i < n) ans = (ans + cal(n / i) * phi[i]) % M;
}
printf("%I64d\n", (ans % M + M) % M / n);
} int main(){
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
init();
scanf("%d", &T);
while (T--){
solve();
}
//fclose(stdin); fclose(stdout);
return ;
}
hdu4048的更多相关文章
随机推荐
- BZOJ1856或洛谷1641 [SCOI2010]生成字符串
BZOJ原题链接 洛谷原题链接 可以将\(1\)和\(0\)的个数和看成是\(x\)轴坐标,个数差看成\(y\)轴坐标. 向右上角走,即\(x\)轴坐标\(+1\),\(y\)轴坐标\(+1\),表示 ...
- ssh密钥讲解
我们用ssh连接机器时候需要输用户名.密码,但是直接写账户文件的时候由于用的是明文,就存在安全的问题了.别人一旦截取了数据就获得了隐私了.这时候就用上ssh的密钥. ssh的密钥存是成对出现的,一个叫 ...
- 2018年设计师都在用的PS切图插件--摹客iDoc
终于找到你,我梦寐以求的PS切图插件.曾几何时,设计师在完成设计稿之后高效的输出标注切图一直是设计师的噩梦.为什么这么说呢?开发要的那么多尺寸,我到底该怎么切图?iPhone的版本已经不少了,更别提安 ...
- keepalived+nginx+tomcat+redis集群环境部署
1.所需软件.jar包.配置文件下载:http://pan.baidu.com/s/1dFgntst 2.环境说明: centos6.5 64位 主节点:192.168.40.121 副节点:192 ...
- 2017/2/16:自己ajax+json习惯性写法 代码拼接的写法 +json用post提交乱码的原因
1.先导入jquery的包 2.ajax的写法跟注意点 返回一个list的写法 代码拼接写法: html层: 2.script处 4:在你前面传递参数的时候没有遇到乱码问题的情况下,你使用json并且 ...
- SHELL脚本取系统当前年月日问题 (去0)
1. #!/bin/bash tmonth=`date +%m`tyear=`date +%y`tday=`date +%d`day=`expr $tday + 0`month=`expr $tmon ...
- sql在最后一行添加合计
select nvl(sno,'合计') sno,sum(score) score from sc group by rollup(sno);
- php中如何解决显示数据库中的内容乱码
第一步: 第二步:在代码开始处加一行
- js中对象继承的冒充方法
function Parent(name){ this.name = name; this.sayName = function(){ console.log(this.name); } } func ...
- RGB转换成YCbCr
clear all; close all; clc; img=imread('colorbar.jpg');%('ngc6543a.jpg'); %img=mat2gray(img); %[0,1]; ...