題目大意:n個大臣進貢的**都是[1,m]內的正整數。若後乙個大臣的**數是後乙個人的倍數,那麼這個人就會受罰。因此他希望你能幫他求出有多少種進貢**的方案,不存在乙個大臣進貢的**恰好是前乙個大臣進貢**的倍數。兩種方案不同當且僅當存在x使得第x個進貢的大臣在兩種方案中進貢了的**數量不同。
題目分析:
一:如果用f[i][j]表示,第i個大臣進貢j的**的方案數。那麼f[i][j]=∑f[i-1][k](j%k!=0),其實可以轉化為:f[i][j]=∑f[i-1][k](m>=k>=1)-∑f[i-1][k](j%k==0)。
二:由於所有的質數在n==1時,f的值為1,那麼因為f[i][j]只與j的因數有關,那麼我們將乙個數分解質因數後可以發現,如果質因數的指數從大到小排序後,兩個數的質因數指數分別相等,那麼他們的f值是相同的,因為都是由同樣數量質數轉移而來的。所以我們只需要處理好質數的組合情況就行了。
三:分析時間複雜度後我們發現,只有當時間複雜度在o(nlogm)左右時才可以通過題目。我們通過打表可以發現,指數組合僅只有不到200種可能性。那麼就可以通過矩陣二分快速冪來實現這個過程,降低時間複雜度,最後時間複雜度大致為o(200^3logn),可以通過題目。
四:在處理指數組合的時候可以用雜湊表來處理。
解題過程:
一:用雜湊表處理處每個指數組合,並記錄每個組合出現的次數。
二:根據1~m的數之間的整除關係來構造矩陣,矩陣i,j表示組合i–>組合j的轉移方案數。
三:利用矩陣二分快速冪迅速得到答案。
最後附上ac**:
#include
#include
#include
#include
#include
using
namespace
std;
typedef
int ll;
ll n,m,p;
ll d[300010],pos[300010];
ll type[210],tot=0;
ll pri=,tp[300010];
void getmax()
}bool cmp(ll a,ll b)
sort(c,c+t,cmp);
ll ans=1,p,c;
while(t--)
for(p=pri[t],c=c[t];c--;)
ans*=p;
if(pos[ans]==-1)
return pos[ans];
}ll cnt[210];
struct matrix
;matrix matrix_mul(matrix a, matrix b)
matrix unit(ll n)
}return ret;
}void matrix_pow(matrix a,ll p,matrix &v)
}ll num[100010];
int main()
matrix m,v;
m.n=tot;
for(ll i=0;ifor(ll j=0;jfor(ll i=0;i0][i]=1;
for(ll i=0;ifor(ll f=1;f*f<=x;++f)
if(f*f!=x)}}
}}
n--;
matrix_pow(m,n,v);
ll a=0;
for(ll i=0;ilong
long)v.a[0][i])%p;
printf("%d\n",a);
return
0;}
TJOI2013 黃金礦工解題報告
小a最近迷上了在上課時玩 礦工 這款遊戲。為了避免被老師發現,他必須小心翼翼,因此他總是輸。在輸掉自己所有的金幣後,他向你求助。每個 可以看做乙個點 沒有體積 現在給出你n個 的座標,挖到它們所需要的時間以及它們的價值。有些 在同一條直線上,這時候你必須按順序挖。你可以瞬間把鉤子轉到任意角度。請你幫...
黃金連分數C 解題
言歸正傳,我們如何求得 分割數的盡可能精確的值呢?有許多方法。比較簡單的一種是用連分數 1 數 11 11 11 1 這個連分數計算的 層數 越多,它的值越接近 分割數。請你利用這一特性,求出 分割數的足夠精確值,要求四捨五入到小數點後100位。小數點後3位的值為 0.618 小數點後4位的值為 0...
Block Voting 解題報告
這道題做的有點狼狽,效率不高,差一點就tle的ac了。看status裡的,ac的時間大多數都是0ms的。肯定有乙個更有效率的演算法的。下面說下我的狼狽演算法。出處 http acm.jlu.edu.cn joj showproblem.php?pid 1223 問題描述 求每個party的權值。第i...