ZYS的黃金 解題報告

2021-08-26 12:41:43 字數 1843 閱讀 4498

題目大意: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...