1. 程式人生 > >HDU 5728 PowMod(數論+遞迴)

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 \