題意:有n種貨幣,每種貨幣有乙個價值vi,並且滿足任意兩種貨幣的價值成倍數關係。
即對於第i種貨幣和第j種貨幣,有vi整除vj,或者vj整除vi。
現在給出這n種貨幣的價值,請你計算有多少種方案能湊出價值為m的貨幣組合。
假設每種貨幣的數量是無限的,貨幣的價值互不相同。
為了保證有解,我們約定存在一種貨幣的價值為1。
由於答案可能很大,你只需要給出答案對998244353取模的值。
設dp[i][j]表示起始用v[i] 終止時用不超過v[j]的硬幣的方案數 那麼構造矩陣行列分別表示起始和終止 那麼我現在想求湊齊所有硬幣的方案數 那麼 我每個硬幣的這個矩陣都可以由前乙個比他小的硬幣快速冪倍增轉移過來 然後求出來之後 我可以假設每次貪心的來做 每次 都在可選區域內選擇最大的來做 那麼假設到達的這些點是關鍵點 那麼我可以知道所有點一定是所有合法方案的必經點 那麼我就每次只計算關鍵點的答案乘起來即可
複雜度n^4log(m)
#include
#include
#include
#define ll long long
#define mod 998244353
#define n 55
using
namespace
std;
inline
char gc()
return *s++;
}inline ll read()
while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=gc();
return x*f;
}struct matrixv[n];
int n;ll m;
inline matrix multiply(const matrix &a,const matrix &b)
inline matrix ksm(matrix b,ll t)ll a[n];
int main()matrix ans;memset(ans.f,0,sizeof(ans.f));for (int i=1;i<=n;++i) ans.f[i][i]=1;
for (int i=n;i;--i) ans=multiply(ksm(v[i],m/a[i]),ans),m%=a[i];ll a=0;
for (int i=1;i<=n;++i) (a+=ans.f[i][n])%=mod;printf("%lld\n",a);
return
0;}
BJ 集訓測試10 城市
圓上均勻分布n 個點 然後 在這n個點中連n 3條邊 且這些邊不相交 有q次詢問每次詢問兩點間的最短距離 因為原圖是平面圖所以可以考慮轉成對偶圖 然後點分治 不想寫對偶圖 點分治可以考慮邊分治 每次選擇一條邊 將這條邊左右的邊的數量盡量平均分布 因為這題比較特殊是在乙個圓環上 所以考慮 我給所有點標...
BJ 集訓測試13 鋼琴
題意給乙個序列 1e6 給乙個字符集大小為n且 100 每次1 n的概率生成其中乙個字元 求每個字首生成的期望 公式 dp i dp next i n i 證明 include define rep i,x,y for register int i x i y i define repd i,x,y...
BJ 集訓測試13 平行
二維直角座標系中有n個點,它們的橫 縱座標的絕對值都不超過10。一次操作,你可以選擇某3個不共線的點a b c。然後以ab為對角線 c為另一頂點繪製平行四邊形abcd,然後用點d替換點c 即刪去點c保留點a b d 則d是確定並且唯一的。最初,n個點的座標互不相同。操作過程中這些點的座標可以重合。但...