Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 661    Accepted Submission(s): 363

Problem Description
On birthday, Anthony got a toy. It is constructed with N+1(N>=3) balls and 2*N sticks. All balls are in a same plane. One of them is special, while the other N balls are connected to it by N sticks with the same length. The angles between any two adjacent sticks are equal. And finally, any two adjacent balls(except the central one) are connected by a stick.
  Here are two examples:

Anthony wanted to remove N sticks, leaving all balls still connected. He wanted to know the number of all legal solutions. Your task is to solve this problem for him. 
  Notice that if a solution will be the same as another one by rotation, these two solutions should be consider as the same. 
The answer may be quite large. You just need to calculate the remainder of the answer when divided by M.
 
Input
Input contains several test cases. 
For each test case, there is only one line containing two integers N and M(3<=N<=10^9, 2<=M<=10^9). 
Input is terminated by EOF.
 
Output
For each case, output one integer in one line, representing the remainder of the number of all solutions when divided by M.

 
Sample Input
3 10000
4 10000
4 10
 
Sample Output
6
13
3
 
Source
 
Recommend
lcy

突然想起MH四baka

数学问题 递推 矩阵加速 快速乘 置换群 burnside引理 欧拉函数

考点真全,真带感

前置技能 本题要用的递推式 Bzoj1002 [FJOI2007]轮状病毒

     置换群 旋转同构计数 POJ2154 Color

     快速乘 HDU5187 zhx's contest

可以发现这题要求的生成树和轮状病毒那题一样,可以用同一个递推式子。

由于n很大,不能直接递推,需要矩阵乘法优化。

然后在外面套一个burnside引理即可。

由于M不一定是质数,不能求逆元,为了保证除法正确性,需要在mod (n*M)的意义下计算,才可以/n

(n*M)的范围是1e18,这使得普通乘法会爆LL,需要加一个快速乘优化。

快速乘不支持乘负数的样子,所以把递推矩阵里的-1加到mod-1,在模意义下等价

理清思路以后就是按模块把代码堆上去,写起来挺爽的。

namespace没什么卵用,但是莫名帅啊

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
using namespace std;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
LL mod;
namespace Euler{
int pri[mxn],cnt=;
bool vis[mxn];
void init(){
for(int i=;i<mxn;i++){
if(!vis[i])
pri[++cnt]=i;
for(int j=;j<=cnt && (LL)pri[j]*i<mxn;j++){
vis[pri[j]*i]=;
if(i%pri[j]==)break;
}
}
return;
}
LL phi(LL x){
LL res=x;
for(int i=;i<=cnt && pri[i]<=x;i++){
if(x%pri[i]==){
res=res/pri[i]*(pri[i]-);
while(x%pri[i]==)x/=pri[i];
}
}
if(x>)res=res/x*(x-);
return res%mod;
}
}
int n,M;
LL f1,f2;
LL ksmul(LL a,LL k){
LL res=;
// printf("ksmul:%lld %lld\n",a,k);
while(k){
if(k&)res+=a; if(res>=mod)res-=mod;
a<<=; if(a>=mod)a-=mod;
k>>=;
}
// printf("d\n");
return res;
}
struct Mat{
LL x[][];
Mat operator * (Mat b){
Mat res;
for(int i=;i<=;i++)
for(int j=;j<=;j++){
res.x[i][j]=;
for(int k=;k<=;k++){
(res.x[i][j]+=ksmul(x[i][k],b.x[k][j]))%=mod;
// printf("i:%d j:%d k:%d\n",i,j,k);
}
}
return res;
}
void init(){
memset(x,,sizeof x);
x[][]=;
x[][]=;
x[][]=;
return;
}
}mp,now;
void ksm(Mat a,LL k){
now.init();
while(k){
if(k&)now=now*a;
a=a*a;
k>>=;
}
return;
}
LL solve(int k){
if(k==)return ;
if(k==)return ;
// printf("solving %d\n",k);
ksm(mp,k-);
// printf("solved %d %lld %lld %lld\n",k,now.x[1][1],now.x[1][2],now.x[1][3]);
return now.x[][];
}
int main(){
using namespace Euler;
int i,j;
init();
mp.x[][]=;
// mp.x[2][1]=-1;
mp.x[][]=;mp.x[][]=;
mp.x[][]=;
while(scanf("%d%d",&n,&M)!=EOF){
mod=(LL)n*M;
mp.x[][]=mod-;
LL ans=;
for(i=;i*i<n;i++){
if(n%i==){
(ans+=ksmul(solve(i),phi(n/i)))%=mod;
(ans+=ksmul(solve(n/i),phi(i)))%=mod;
}
}
if(i*i==n) (ans+=solve(i)*phi(i))%=mod;
ans/=n;
printf("%lld\n",ans);
}
return ;
}

HDU2481 Toy的更多相关文章

  1. BZOJ 1010: [HNOI2008]玩具装箱toy [DP 斜率优化]

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 9812  Solved: 3978[Submit][St ...

  2. POJ 2398 Toy Storage(计算几何)

    题意:给定一个如上的长方形箱子,中间有n条线段,将其分为n+1个区域,给定m个玩具的坐标,统计每个区域中的玩具个数. 题解:通过斜率判断一个点是否在两条线段之间. /** 通过斜率比较点是否在两线段之 ...

  3. Codeforces Round #238 (Div. 2) D. Toy Sum(想法题)

     传送门 Description Little Chris is very keen on his toy blocks. His teacher, however, wants Chris to s ...

  4. 【BZOJ-1010】玩具装箱toy DP + 斜率优化

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 8432  Solved: 3338[Submit][St ...

  5. ACM/ICPC 之 BFS(离线)+康拓展开(TSH OJ-玩具(Toy))

    祝大家新年快乐,相信在新的一年里一定有我们自己的梦! 这是一个简化的魔板问题,只需输出步骤即可. 玩具(Toy) 描述 ZC神最擅长逻辑推理,一日,他给大家讲述起自己儿时的数字玩具. 该玩具酷似魔方, ...

  6. [LintCode] Toy Factory 玩具工厂

    Factory is a design pattern in common usage. Please implement a ToyFactory which can generate proper ...

  7. POJ 2398 - Toy Storage 点与直线位置关系

    Toy Storage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5439   Accepted: 3234 Descr ...

  8. BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP

    1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...

  9. 简单几何(点与线段的位置) POJ 2318 TOYS && POJ 2398 Toy Storage

    题目传送门 题意:POJ 2318 有一个长方形,用线段划分若干区域,给若干个点,问每个区域点的分布情况 分析:点和线段的位置判断可以用叉积判断.给的线段是排好序的,但是点是无序的,所以可以用二分优化 ...

随机推荐

  1. 可用率map处理

    total_data =[ {'event_current_dealer': '陈铁', 'id__count': 66}, {'event_current_dealer': '丁凯', 'id__c ...

  2. Unity3d工具方法小集

    1.获取垂直水平方向上的输入: float moveHorizontal = Input.GetAxis("Horizontal"); float moveVertical = I ...

  3. SVN被锁定如何解决?

    报错: “E:/SVN被锁定” 请进行清理操作 解决方式: 1.试着右击进行解锁 没有解决 2.试着进行清理,清理后再做更新操作 好的成功. OK能正常使用了. 2017年10月26日更新 报错: s ...

  4. Qt Qwdget 汽车仪表知识点拆解3 进度条编写

    先贴上效果图,注意,没有写逻辑,都是乱动的 这篇我来说说左侧的这个进度条的实现原理,其实更简单,哈哈哈 有一个大的widget,根据素材,我放了10个label 剩下的就是写一个函数,根据数据的不同, ...

  5. 深挖 NGUI 基础 之UIRoot (一)

    当你开始使用NGUI的时候,简单的从项目视图 中一个”Control”预设体 拖拽到场景视图中,你将会发现 Hierarchy层次面板中会出现以下层次结构: 其中 UI Root作为根节点,是每个NG ...

  6. centos7.4内核从3.10升级到4.14详细步骤

    由于我们的docker学习中的Overlay需要内核版本在3.12+,所以在安装完centos7.4之后要进行内核升级,下面是升级步骤:1.导入keyrpm --import https://www. ...

  7. 并查集——poj1182(带权并查集高阶)

    题目链接:食物链 题解:点击 说一声:这题关系推导值得学习.

  8. VS2015中常用快捷键的修改推荐

    首先,在VS2015中修改快捷键的步骤如下: 工具--选项--环境--键盘. 如图: 然后就是修改快捷键:(以下是个人的使用习惯,仅供参考) 1.编辑.设置选定内容的格式.设置为ctrl+E,Ctrl ...

  9. 【EasyNetQ】- 多态发布和订阅

    您可以订阅接口,然后发布该接口的实现. 我们来看一个例子.我有一个接口IAnimal和两个实现Cat和Dog: public interface IAnimal { string Name { get ...

  10. C# 利用WMI对象获取物理内存和可用内存大小

    下面的代码演示的是使用WMI对象可获取取物理内存和可用内存大小,在使用WMI对象前,先要添加对System.Management的引用,然后就可以调用WMI对象,代码如下: //获取总物理内存大小 M ...