HDU 5728 PowMod(數論+遞迴)
Description
定義,其中n無平方因數,是尤拉函式
現給出n,m,p,求 ,式子中k有無窮個
Input
第一行為一整數T表示用例組數,每組用例佔一行包括三個整數n,m,p
(T<=100,1<=n,m,p<=10^7)
Output
對於每組用例,輸出ans
Sample Input
1 2 6
1 100 9
Sample Output
4
7
Solution
首先求k,需要用到尤拉函式的兩個性質:
1.若(n,m)=1,則有
2.若m是素數且m|n,則有
由這兩個性質有:
記solve(n,m)=,p為n的素因子,則有
當n=1時,solve(1,m)=
當m=1時,solve(n,1)=;
當m=0時,solve(n,0)=0;
這個遞迴求解最多遞迴n的素因子個數層,故可以在至多O(log n)的複雜度內求出k,下面來求ans
此處引入一個由尤拉定理衍生出的一個指數迴圈節定理
每次往上冪一層模數就取一次尤拉函式值,由於一個數的尤拉函式值一定小於自身,所以至多經過O(log p)次操作模數就變成了1,那麼上面的冪就沒有意義了,無限冪就變成了有限冪
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
#define maxn 11111111
#define mod 1000000007ll
int euler[maxn],prime[maxn],sum[maxn],res;
void get_euler()
{
memset(euler,0,sizeof(euler));
euler[1]=1,sum[1]=1;
res=0;
for(int i=2;i<maxn;i++)
{
if(!euler[i])
{
euler[i]=i-1 ;
prime[res++]=i;
}
for(int j=0;j<res&&prime[j]*i<maxn;j++)
{
if(i%prime[j])
euler[prime[j]*i]=euler[i]*(prime[j]-1);
else
{
euler[prime[j]*i]=euler[i]*prime[j];
break;
}
}
sum[i]=(sum[i-1]+euler[i])%mod;
}
}
int solve(int n,int m)
{
if(n==1)return sum[m];
if(m==1)return euler[n];
if(m==0)return 0;
for(int i=0;i<res;i++)
if(n%prime[i]==0)
return (1ll*(prime[i]-1)*solve(n/prime[i],m)%mod+solve(n,m/prime[i]))%mod;
}
ll mod_pow(ll a,ll b,int p)
{
ll ans=1;
while(b)
{
if(b&1)ans=ans*a%p;
a=a*a%p;
b>>=1;
}
return ans;
}
int deal(int k,int p)
{
if(p==1)return 0;
ll temp=deal(k,euler[p]);
return mod_pow(k,temp+euler[p],p)%p;
}
int main()
{
get_euler();
int n,m,p;
while(~scanf("%d%d%d",&n,&m,&p))
{
ll k=solve(n,m);
int ans=deal(k,p);
printf("%d\n",ans);
}
return 0;
}
相關推薦
HDU 5728 PowMod(數論+遞迴)
Description 定義,其中n無平方因數,是尤拉函式 現給出n,m,p,求 ,式子中k有無窮個 Input 第一行為一整數T表示用例組數,每組用例佔一行包括三個整數n,m,p (T&l
HDU 5728 PowMod(數論,尤拉函式的各種性質)
[題意] k=∑i=1mϕ(i∗n)%1000000007 其中n為無平方因子的數,求 ans=kkkk...k%p [分析] n無平方因子說明n可以表示為n=p1∗p2∗...∗pl
CodeForces 83D Numbers (數論+遞迴)*
#include<bits/stdc++.h> using namespace std; #define debug puts("YES"); #define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++) #def
hdu 1007 Quoit Design (分治+遞迴)
題意就是輸入一堆點在二維平面上的座標,找出距離最短的兩個點對,距離除以2輸出。 很簡單的遞迴加分治。然而我昨天寫的時候WA到心態爆炸,今天終於明白整個結構都有問題,重新修改了一遍,直接過了。 附上程式碼: #include<iostream> #include<cs
[HDU 5728] PowMod (尤拉函式的積性+尤拉公式降冪+尤拉篩)
HDU - 5728 求 K=∑i=1mϕ(i∗n)mod1000000007 其中 n是 square-free number 求 ans=KKKK..modp 先求 K 由於 ϕ(n)是積性函式,所以對於 n的每個素因子可以提出
【資料結構】二叉樹的建立和遍歷(非遞迴)
該程式使用的是遞迴地建立方法,以及非遞迴的遍歷演算法 執行環境:Dev-C++ #include <stdio.h> #include <stdlib.h> typedef struct node{ char data; struct node *lchild
python 學習彙總36:遞迴函式(尾遞迴)( tcy)
遞迴函式(尾遞迴) 2018/11/15 用途: 遞迴函式常用於檢索大量資料,替代for迴圈。 1.遞迴深度設定: sys.getrecursionlimit() #返回
三元組矩陣行列式的計算(用遞迴)
1.具體思想: 關於計算矩陣行列式有兩個主要方法: 1.根據居住行列式的定義式用遞迴計算(就是本文所講) 2.先做矩陣行變換,轉化為上三角矩陣,再求行列式。 (我先是思考了行變換轉化為三角矩陣,但中途遇到了些問題,所以先把遞迴的方法寫下來,之後會繼續更新另外一種方法。) 線性代數裡我
折半查詢(非遞迴)
設有n個數據儲存於有序資料表中,在進行折半查詢之前,先找出資料表中的正中元素的下標mid,利用其關鍵碼L.Data[mid]與定值x作比較。 若x.key=L.Data[mid].key,查詢成功,返回其下標mid並報告成功; &nb
全排列演算法(使用遞迴)
問題描述 對於任意的n個字母,實現其的全排列,並查詢第m個,其排列形式。我寫的這個程式碼中主要用的遞迴。 程式碼如下 #include<stdio.h>int n,book[10],k; &nbs
巨人與鬼(分治&&遞迴)
做這一題學會了 atan2 的用法。 a(x1,y1) b(x2,y2) 向量a=>b = (y2 - y1)/ (x2 - x1) 與x軸正半軸的夾角為 atan2( y2 - y1,x2 - x1)。。。。。 我寫這篇部落
c++中求1!+2!+3!+...+20!(不用遞迴)
c++中求1!+2!+3!+…+20!(不用遞迴) #include "stdafx.h" #include<iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) {
Unity編譯器之快捷新增碰撞器,和移除碰撞器(運用遞迴)
在實際做專案中,有時候經常需要對地形的碰撞體進行編輯,比如很多不需要加碰撞體的物件卻帶著碰撞體,如果手動去移除,工作量又是很大(經常子物體又是套著子物體,十分複雜),有時候又需要新增碰撞體,本人就移除碰撞體這件事件花了很長時間,不勝其煩,網上的資料也不是太多,也不全。所以在這給大家貼出流程與程式碼。
Codeforces Round #223 (Div. 2): C. Sereja and Prefixes(二分+遞迴)
題意: 你有一個序列,一開始為空,之後進行m次操作,操作有兩種: 1 x:在當前序列後面新增一個數x 2 x, y:將序列的前x個數複製y遍接序列後面(x<10000) 之後n次
十進位制轉換二進位制C++實現(非遞迴)
實現十進位制轉換為二進位制非遞迴實現 以下是C++原始碼: #include<iostream> #include<stdio.h> using namespace std; //十進位制 轉換為 二進位制------非遞迴 int DecToBin(int de
VUE-開發一個樹形結構元件(元件遞迴)
需求 一個頁面,要顯示商品分類,同時每個分類下面還擁有若干子類,子類也可以有子類。 要實現全選單選,子類被逐個全選父類也要標記選中。 第一反應就是樹形結構,和遞迴呼叫。曾經在做WPF時記得有現成的元件,也學著寫過對應的後臺。這次我要自己寫一個前端的元件了。 這只是我自己花了點時間寫的一個
翻轉連結串列(非遞迴)
1. 問題描述: 給出一個連結串列,翻轉連結串列,返回翻轉後連結串列的頭結點 2. 我們也可以使用非遞迴的方式來進行翻轉連結串列,首先遍歷連結串列,使用一個指標pre記錄當前節點的前一個節點,使用當前節點的next指向前一個節點pre,即下一個元素的指標next指向前一個元素pre那麼就實現
二分搜尋(非遞迴)
1 public class Main{ 2 public static int binarySearch(int a[],int x,int n) { 3 int left=0; 4 int right=n-1; 5 while(lef
資料結構:歸併排序(非遞迴)
前言 歸併排序,是建立在歸併操作上的一種有效的排序演算法,效率為O(nlogn)。1945年由約翰·馮·諾伊曼首次提出。該演算法是採用分治法的一個非常典型的應用,且各層分治遞迴可以同時進行。(引自維基百科) 原理 以上視訊轉自www.youtube.com/watch?v=JSc… 由於掘金中無法
LintCode Binary Tree Inorder Traversal 二叉樹的中序遍歷(非遞迴)
給出一棵二叉樹,返回其中序遍歷。 Given a binary tree, return the inorder traversal of its nodes’ values. 樣例 給出二叉樹 {1,#,2,3}, 1 \