題意:求npm,即n個元素的m中排列方式結果中末尾非0 的數字。
思路: 首先我們知道,2和5相乘末尾非0數字為1,相當於可以相消。我們先把這兩個因子抽離出來,考慮末尾為3,7,9的數字。
設f(n,x)為:n!因子中,抽離了2,5,後末尾數字為x的因子個數。分析可以知道f(n,x)=f(n/2,x)+g(n,x);g(n,x)表示n!中所有奇因子末尾數字為x的因子個數。
可以這樣分析,對於n!的每乙個因子k,如果k是偶數則除二納入到f(n/2,x)中,如果k是奇數則到g(n,x)中,這樣就有了上面那條式子。
接下來分析g(n,x),顯然n/10肯定是要的,因為以10為週期,肯定包含3,7,9中的乙個,如果n%10>=x,那麼加1,還要加上因子中抽離5後的數g(n/5,x)。
所以g(n,x)=n/10+(n%10>=x)+g(n/5,x);
對於2,5的因子個數可以這樣求,getx(n,x),x=2,5,getx(n,x)=getx(n/x,x)+n/x;
現在要算的是n!/m!的結果,因為結果肯定是整數,所以因子個數可以直接相減,
把2,3,5,7,9的數目求出來後,要比較2,5因子個數誰多,2多就要減去5的(相消),相等就兩個都不要,5多就要乘以5.
剩下3,7,9因子指數相乘時有個迴圈節,mod3[4]=;mod7[4]=;mod9[4]=;
看有多少個因子數直接可以得出cnt個x的因子相乘的末尾數。
#include #include #include #include #include #include #include #include using namespace std;
#define rep(i,a,b) for(int i=a;i=x)+g(n/5,x);
}int f(int n,int x)
int getx(int n,int x)
{ if(n>n>>m)
{m=n-m;
cnt[2]=getx(n,2)-getx(m,2);
cnt[3]=f(n,3)-f(m,3);
cnt[5]=getx(n,5)-getx(m,5);
cnt[7]=f(n,7)-f(m,7);
cnt[9]=f(n,9)-f(m,9);
//cnt[2]-=cnt[5];
int ans=1;
if(cnt[2]>cnt[5])
ans*=mod2[(cnt[2]-cnt[5])%4];
else if(cnt[2]==cnt[5]) ;
else ans*=5;
ans*=mod3[cnt[3]%4];
//ans*=mod5[cnt[5]%4];
ans*=mod7[cnt[7]%4];
ans*=mod9[cnt[9]%4];
ans%=10;
cout<
poj1150排列最後地非零位 數學
排列最後地非零位有2,5,3,7,9地次方來決定,而且這幾個數地次方最後一位都是週期出現。在計算地過程中先找出1 n中有多少2和5地冪,比如找2,先找出偶然n 2個,然後 2,再找。找到2和5地冪,比大小處理。末尾數字3,5,7地處理花了寫時間,先用處理類似2,5地迴圈來寫總是出錯。手工花了資料,發...
n 最後一位非零數 poj 1150
題意 求p n,m 的最後一位非零數。思路 討論1 n中2,5,3,7,9因子的個數,具體移步 按照我的理解,求n!最後非零為,先把1 n中 2 和 5 的因子的數量求出來,因為只有2和5可以構成0,接下來就要分別求出1 n中最後一位為3,7,9的數字的數量,然後相乘就可以得到n!的最後一位的數 i...
poj求排列的逆序數
此題為分治法歸併 總時間限制 1000ms 記憶體限制 65536kb 描述在internet上的搜尋引擎經常需要對資訊進行比較,比如可以通過某個人對一些事物的排名來估計他 或她 對各種不同資訊的興趣,從而實現個性化的服務。對於不同的排名結果可以用逆序來評價它們之間的差異。考慮1,2,n的排列i1,...