POJ2154 Color【 polya定理+欧拉函数优化】(三个例题)
由于这是第一天去实现polya题,所以由易到难,先来个铺垫题(假设读者是看过课件的,不然可能会对有些“显然”的地方会看不懂):
一:POJ1286 Necklace of Beads :有三种颜色,问可以翻转,可以旋转的染色方案数,n<24。
1,n比较小,恶意的揣测出题人很有可能出超级多组数据,所以先打表。
2,考虑旋转:
for(i=;i<n;i++) sum+=pow(n,gcd(n,i));
3,考虑翻转:
if(n&) sum+=n*pow(,n/+) ;
else {
sum+=n/*pow(,n/) ;
sum+=n/*pow(,n/+) ;
}
4,除以总置换数(2*n=n+n/2+n/2):
sum/=(*n);
5,终极代码:
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
#define ll long long
ll ans[];
ll gcd(ll a,ll b) { if(b==) return a; return gcd(b,a%b); }
ll pow(ll a,ll x)
{
ll res=;
while(x){
if(x&) res*=a;
x>>=;
a*=a;
} return res;
}
int main()
{
ll n,i,sum;
for(n=;n<=;n++){
sum=;
for(i=;i<n;i++) sum+=pow(,gcd(n,i));
if(n&) sum+=n*pow(,n/+) ;
else {
sum+=n/*pow(,n/) ;
sum+=n/*pow(,n/+) ;
}
ans[n]=sum/n/;
}
while(~scanf("%lld",&n)){
if(n==-) return ;
printf("%lld\n",ans[n]);
}
return ;
}
二:HDU3923:Invoker :把3改成m即可。
1,注意有乘法的话担心超int还是用long long保险。
2,注意除置换群2*n的时候要逆元。。。比赛的时候就是没有加逆元,导致我牛客第四场排名15。。。不然连续5场前10挺好的。。。
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
const int Mod=;
#define ll long long
int gcd(int a,int b) { if(b==) return a; return gcd(b,a%b); }
int qpow(int a,int x)
{
int res=;a%=Mod;
while(x){
if(x&) res=(ll)res*a%Mod;
x>>=;
a=(ll)a*a%Mod;
} return res;
}
int main()
{
int T,n,m,i,Case=,ans;
scanf("%d",&T); while(T--){
scanf("%d%d",&m,&n);
ans=;
for(i=;i<n;i++) ans=(ans+qpow(m,gcd(n,i)))%Mod;
if(n&) ans=(ans+n*qpow(m,n/+))%Mod;
else {
ans=(ans+n/*qpow(m,n/))%Mod;
ans=(ans+n/*qpow(m,n/+))%Mod;
}
ans=(ll)ans%Mod*qpow(*n,Mod-)%Mod;
printf("Case #%d: %d\n",++Case,ans);
}
return ;
}
----------------------------------------------------分界线----------------------------------------------------
下面的需要加优化了。
三:POJ2154 Color: 求可以旋转,不可以翻转的置换,n个珠子,n种颜色,答案mod K,n<1e9。
那么本题只考虑旋转,则:
for(i=;i<n;i++) ans+=pow(n,gcd(n,i));
ans/=n;
之前莫比乌斯那里,我们常用技巧是合并。 这里考虑gcd相同的合并。(做多了还是有点灵感滴,yeah)。
得到:
解决这个公式需要:快速幂+欧拉函数+一些素数的常识。
1,快速幂不说了,注意先模运算。
2,欧拉函数,枚举L,即n的素因子,然后根据phi=L*(1-1/p1)*(1-1/p2)...得到欧拉函数。
3,素数常识,在这里指的是一个数n的素因子最多有一个大于根号n,所以一直除,把根号n前的素数都除完了,留下的一定是大于根号n的一个素数。
//可以线筛一部分欧拉函数出来,不够的再枚举素数;枚举的话不超过根号个,所以复杂度不会太高。
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=;
int ans, Mod;
int pri[maxn+],cnt,vis[maxn+],phi[maxn+];
int qpow(int a,int x)
{
int res=;a%=Mod;//这里a一定要除一下,不然会超int,猪啊。
while(x){
if(x&) res=res*a%Mod;
x>>=; a=a*a%Mod;
} return res%Mod;
}
void prime()
{
phi[]=;
for(int i=;i<=maxn;i++){
if(!vis[i]) pri[++cnt]=i,phi[i]=i-;
for(int j=;j<=cnt&&pri[j]*i<=maxn;j++) {
vis[pri[j]*i]=;
if(i%pri[j]==) {
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
else phi[i*pri[j]]=phi[i]*(pri[j]-);
}
}
}
int Phi(int x)
{
if(x<=maxn) return phi[x]%Mod;
int res=x;
for(int i=;pri[i]*pri[i]<=x;i++)
if(x%pri[i]==){
res=(res-res/pri[i]);
while(x%pri[i]==) x/=pri[i];
}
if(x!=) res=(res-res/x);
return res%Mod;
}
int main()
{
int n,T; prime();
scanf("%d",&T);
while(T--){
ans=; scanf("%d%d",&n,&Mod);
for(int i=;i*i<=n;i++){
if(n%i!=) continue;
ans=(ans+qpow(n,i-)*Phi(n/i))%Mod;
if(i*i!=n) ans=(ans+qpow(n,n/i-)*Phi(i))%Mod;
}
printf("%d\n",ans);
} return ;
}
--------------------【优化】-----------
--------------------【here】-------------
这些基本的都可以用欧拉函数来优化,比如上面的第二个例子。
上面的代码是500+ms。
优化后0ms。
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=;
const int Mod=1e9+;
#define ll long long
ll ans;
ll pri[maxn+],cnt,vis[maxn+],phi[maxn+];
ll qpow(ll a,ll x)
{
ll res=;a%=Mod;//这里a一定要除一下,不然会超int,猪啊。
while(x){
if(x&) res=res*a%Mod;
x>>=; a=a*a%Mod;
} return res%Mod;
}
void prime()
{
phi[]=;
for(int i=;i<=maxn;i++){
if(!vis[i]) pri[++cnt]=i,phi[i]=i-;
for(int j=;j<=cnt&&pri[j]*i<=maxn;j++) {
vis[pri[j]*i]=;
if(i%pri[j]==) {
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
else phi[i*pri[j]]=phi[i]*(pri[j]-);
}
}
}
int main()
{
ll n,m,T,Case=; prime();
scanf("%lld",&T);
while(T--){
ans=; scanf("%lld%lld",&m,&n);
for(ll i=;i*i<=n;i++){
if(n%i!=) continue;
ans=(ans+qpow(m,i)*phi[n/i])%Mod;
if(i*i!=n) ans=(ans+qpow(m,n/i)*phi[i])%Mod;
}
if(n&) ans=(ans+n*qpow(m,n/+))%Mod;
else {
ans=(ans+n/*qpow(m,n/))%Mod;
ans=(ans+n/*qpow(m,n/+))%Mod;
}
ans=ans%Mod*qpow(*n,Mod-)%Mod;
printf("Case #%lld: %lld\n",++Case,ans);
} return ;
}
其他类似的题目还有,HDOJ:2084、2647、1812、3411、2865、2481。POJ:1286、2409、2154、2888。
POJ2154 Color【 polya定理+欧拉函数优化】(三个例题)的更多相关文章
- 【poj2154】Color Polya定理+欧拉函数
题目描述 $T$ 组询问,用 $n$ 种颜色去染 $n$ 个点的环,旋转后相同视为同构.求不同构的环的个数模 $p$ 的结果. $T\le 3500,n\le 10^9,p\le 30000$ . 题 ...
- poj2154Color polya定理+欧拉函数优化
没想到贱贱的数据居然是错的..搞得我调了一中午+晚上一小时(哦不d飞LJH掉RP毕竟他是BUFF)结果重判就对了五次.. 回归正题,这题傻子都看得出是polya定理(如果你不是傻子就看这里),还没有翻 ...
- poj2409 & 2154 polya计数+欧拉函数优化
这两个题都是项链珠子的染色问题 也是polya定理的最基本和最经典的应用之一 题目大意: 用m种颜色染n个珠子构成的项链,问最终形成的等价类有多少种 项链是一个环.通过旋转或者镜像对称都可以得到置换 ...
- poj 2154 Color(polya计数 + 欧拉函数优化)
http://poj.org/problem?id=2154 大致题意:由n个珠子,n种颜色,组成一个项链.要求不同的项链数目.旋转后一样的属于同一种.结果模p. n个珠子应该有n种旋转置换.每种置换 ...
- POJ2154 Color 【Polya定理 + 欧拉函数】
题目 Beads of N colors are connected together into a circular necklace of N beads (N<=1000000000). ...
- poj2154(polya定理+欧拉函数)
题目链接:http://poj.org/problem?id=2154 题意:n 种颜色的珠子构成一个长为 n 的环,每种颜色珠子个数无限,也不一定要用上所有颜色,旋转可以得到状态只算一种,问有多少种 ...
- poj 2154 Color【polya定理+欧拉函数】
根据polya定理,答案应该是 \[ \frac{1}{n}\sum_{i=1}^{n}n^{gcd(i,n)} \] 但是这个显然不能直接求,因为n是1e9级别的,所以推一波式子: \[ \frac ...
- 【POJ2154】Color Pólya定理+欧拉函数
[POJ2154]Color 题意:求用$n$种颜色染$n$个珠子的项链的方案数.在旋转后相同的方案算作一种.答案对$P$取模. 询问次数$\le 3500$,$n\le 10^9,P\le 3000 ...
- Luogu4980 【模板】Polya定理(Polya定理+欧拉函数)
对于置换0→i,1→i+1……,其中包含0的循环的元素个数显然是n/gcd(i,n),由对称性,循环节个数即为gcd(i,n). 那么要求的即为Σngcd(i,n)/n(i=0~n-1,也即1~n). ...
随机推荐
- Unable to satisfy the following requirements解决方式
今天从git上面download我们项目,然后向往常一样安装Cocoapods.可是却突然发现报错了,尝试了几遍.发现一直报错. 然后我这才看了一下,安装Cocoapods的日志,发现抛出了一个报错. ...
- openCV—Python(1)——初始化环境
本系列博客主要參考自--Adrian Rosebrock:<Practical Python and OpenCV: An Introductory,Example Driven Guide t ...
- 浅谈PropertyChanged是如何被初始化的?
http://www.cnblogs.com/wpcockroach/p/3909081.html
- 为什么应使用 Node.js
为什么应使用 Node.js JavaScript 高涨的人气带来了很多变化,以至于如今使用其进行网络开发的形式也变得截然不同了.就如同在浏览器中一样,现在我们也可以在服务器上运行 JavaScrip ...
- Android异步载入AsyncTask具体解释
曾看见有人说过.认为非常有道理.分享一下: 技术分为术和道两种: (1)具体做事的方法是术. (2)做事的原理和原则是道. 近期项目发现个重大问题.结果打log跟踪查是AsyncTask导 ...
- java模拟而一个电话本操作
哈哈.大家平时都在使用电话本.以下使用java来模拟而一个简单的电话本吧... 首先给出联系人的抽象类 package net.itaem.po; /** * * 电话人的信息 * */ public ...
- OpenCV 的四大模块
前言 我们都知道 OpenCV 是一个开源的计算机视觉库,那么里面到底有哪些东西?本文将为你解答这个问题. 模块一:CV 这个模块是 OpenCV 的核心,它包含了基本的图像处理函数和高级的计算机视觉 ...
- Xcode5.1.1+ios 7.1.2 免证书真机调试
Xcode假设不破解.无法真机调试, 也无法编译真机Release文件.仅仅有付费开通Apple开发人员账号,才干申请真机调试.而Xcode进行破解后,结合越狱的iPhone或iPad, 就可以免官方 ...
- 2016/7/7 设置wamp2.5 mysql密码 重点是mysql版本
密码设置时要注意mysql版本.版本不同,效果不同. 方法/步骤 安装好wamp后,右击wamp->MySQl->MySql console(控制台) 提示输入密码,因为密码为 ...
- 开源安卓Android流媒体音视频播放器实现声音自动停止、恢复、一键静音功能源码
本文转自EasyDarwin团队John的博客:http://blog.csdn.net/jyt0551/article/details/60802145 我们在开发安卓Android流媒体音视频播放 ...