背景
yxy's revenge(yxy的复仇)
yxy逃出了JZP的迷宫,他趁JZP在酣睡的时候把JZP给拖走了....
描述
当JZP再次醒来时,发现他在yxy的地盘上。
他发现他进入了一个祖玛游戏:地上有一圈槽形成一个圆,他在圆心上。在一圈槽上有n个可以摆放球的地方,在他的旁边有m个洞,可以从每个洞都可以拿到无限多的一种球(有红的,黄的,绿的...)。
JZP将这m种球放在这n个槽里,问他能摆多少种情况(如果将圆翻折和旋转一样则视为一种,不可以不放球)。
格式
输入格式
两个数 n,m(n<=3000,m<=3000)
输出格式
一个数,即所有情况数
这题是典型的polya问题,都是普通的旋转和翻折置换可以套模板,然而看交流区都说要用高精度之类的,暂时不太会用,刚刚看java两三天就试着用大数类写了一下。结果还是只能过7个点,最后T了3个点也不知道为啥。
若以后用高精度过了再更新。
附上没全过的java代码和基础的polya模板。
//package helloworld;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Scanner;
import java.math.*;
public class Main {
public static BigInteger gcd(BigInteger a,BigInteger b){
if(b==BigInteger.valueOf(0)) return a;
else return gcd(b,a.mod(b));
}
public static BigInteger Pow(BigInteger a,long b){
BigInteger ans=BigInteger.valueOf(1);
for(;b!=0;b>>=1,a=a.multiply(a))
if((b&1)==1)
ans=ans.multiply(a);
return ans;
}
public static BigInteger polya(BigInteger n,BigInteger c){
BigInteger ans=BigInteger.valueOf(0);
for(int i=1;i<=n.intValue();i++){
ans=ans.add(Pow(c,(gcd(n,BigInteger.valueOf(i)).longValue())));
// System.out.println((Pow(c,(gcd(n,BigInteger.valueOf(i)).longValue()))));
}
if((n.intValue()&1)==1){
ans=ans.add(n.multiply(Pow(c,((n.divide(BigInteger.valueOf(2))).add(BigInteger.valueOf(1)).longValue()))));
// System.out.println(ans);
}
else{
for(int i=1;i<=n.intValue();i++)
if((i&1)==1) ans=ans.add(Pow(c,(n.divide(BigInteger.valueOf(2))).add(BigInteger.valueOf(1)).longValue()));
else ans=ans.add(Pow(c,(n.divide(BigInteger.valueOf(2)).longValue())));
}
// System.out.println(ans);
return ans.divide(n.multiply(BigInteger.valueOf(2)));
}
public static void main(String[] args) {
Scanner in =new Scanner(System.in);
int n,m;
while(in.hasNext()){
n=in.nextInt();
m=in.nextInt();
System.out.println(polya(BigInteger.valueOf(n),BigInteger.valueOf(m)));
}
}
}
基础polya模板(C++):
LL Pow(int a,int b){
return b==0?1:Pow(a,b-1)*a;
}
int gcd(int a,int b){
if(!b) return a;
else return gcd(b,a%b);
}
LL polya(int c,int s){
LL sum=0;
for(int i=1;i<=s;i++)
sum+=Pow(c,gcd(s,i));
if(s&1)
sum+=s*Pow(c,(s>>1)+1);
else{
for(int i=1;i<=s;i++)
if(i&1)
sum+=Pow(c,(s>>1)+1);
else
sum+=Pow(c,s>>1);
}
return sum/2/s;
}