loop|loop.in|loop.outios
題目描述:oop
有N個點。測試
如今重複這樣的操做:spa
隨機找一個出度爲0的點p1,隨機找一個入度爲0的點p2,連一條有向邊從p1指向p2。直到沒有出度爲0的點。code
統計最終狀態這個圖中的環的指望個數。blog
爲了保證答案精度,提供另一個參數W(正整數),請你輸出小於你的答案乘上W後的最大整數。string
輸入格式:it
一行兩個整數N,W。io
輸出格式:class
一行一個整數(保證不超過10^6)。
樣例輸入(多組,測試數據中只有一組):
1 100
2 100
樣例輸出:
99
149
數據範圍:
30% N<=100
70% N<=5*10^6
100% N<=10^18
這道題思路很經典,一個閉環等同於消失,一條鏈等同於一個點,最後指望值爲:f(n)=1/1+1/2+1/3+...+1/n
f(n)爲發散的,然而f(n)-ln(n)爲收斂的,極值爲歐拉常數0.57721566490153286060651209。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; typedef long double real; #define PROB "loop" #define eps 1e-30 #define lim 0.577215 real ans=0; int main() { freopen(PROB".in","r",stdin); // freopen(PROB".out","w",stdout); int i,j,k,x,y,z,w; long long n; scanf("%lld%d",&n,&w); if (n<=100000) { for (i=1;i<=n;i++) { ans+=(real)1.0/i; } }else { ans=log(n)+lim; } int ans2; // real ans3=log(n)+lim; ans2=ceil(ans*w); printf("%d",ans2-1); }