vijos1556 祖玛游戏

背景

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;  
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值