日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU 2865 Birthday Toy [Polya 矩阵乘法]

發布時間:2025/6/15 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU 2865 Birthday Toy [Polya 矩阵乘法] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

傳送門

題意:

相鄰珠子不能相同,旋轉等價。$n$個珠子$k$中顏色,求方案數


?

首先中間珠子$k$種選擇,$k--$
如果沒有相鄰不同的限制,就和$POJ\ 2154$一樣了
$|C(f)|=k^{\#(f)}$
但是有了相鄰不同的限制,每種循環的顏色就不能任意選擇了
旋轉等價循環個數是$gcd(n,i)$,同一個循環的元素相差$i$步
容易得到只要滿足長度$gcd(n,i)$的一段相鄰顏色不同整個環就不同了,因為這樣的一段正好每個循環有一個元素
考慮$DP$,$f[i]$表示$i$個元素組成的環染色方案數
$f[i]=(k-2)*f[i-1]+(k-1)*f[i-2]$
因為這時候$i-1$是可以和$1$相同的,那樣$i$有$k-1$種選擇,所以加上后面的一塊
顯然可以用矩陣快速冪
計算的時候使用和和$POJ\ 2154$同樣的技巧
最后的式子為:
$\frac{k}{n}\sum\limits_{d \mid n}{f(d)*\phi(\frac{n}ozvdkddzhkzd)},\ d \neq 1$

?

注意:$Candy?$把矩陣的構造函數里加上了每個矩陣都初始化為單位矩陣,認為這樣就不用在做矩陣快速冪前初始化了。

然后就被坑慘了......矩陣乘法里還需要零矩陣啊啊啊啊啊啊啊?

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N=1e5+5,P=1e9+7; typedef long long ll; inline int read(){char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}return x*f; } int n; ll k; int p[N]; bool notp[N]; void sieve(int n){for(int i=2;i<=n;i++){if(!notp[i]) p[++p[0]]=i;for(int j=1;j<=p[0]&&i*p[j]<=n;j++){notp[i*p[j]]=1;if(i%p[j]==0) break;}} } inline int phi(int n){int re=n,m=sqrt(n);for(int i=1;i<=p[0]&&p[i]<=m&&p[i]<=n;i++) if(n%p[i]==0){re=re/p[i]*(p[i]-1);while(n%p[i]==0) n/=p[i];}if(n>1) re=re/n*(n-1);return re%P; } struct Matrix{ll a[2][2];ll* operator [](int x){return a[x];}Matrix(){a[0][0]=a[1][1]=a[0][1]=a[1][0]=0;}void ini(){a[0][0]=a[1][1]=1;} }a,b; Matrix operator *(Matrix a,Matrix b){Matrix c;for(int k=0;k<2;k++)for(int i=0;i<2;i++) if(a[i][k])for(int j=0;j<2;j++) if(b[k][j])(c[i][j]+=a[i][k]*b[k][j])%=P;return c; } Matrix operator ^(Matrix a,int b){Matrix re;re.ini();for(;b;b>>=1,a=a*a)if(b&1) re=re*a;return re; } ll F[5]; ll f(int x){if(x<=3) return F[x];Matrix re=a^(x-3);re=re*b;return re[0][0]; } inline void mod(int &x){if(x>=P) x-=P;} inline ll Pow(ll a,int b){ll re=1;for(;b;b>>=1,a=a*a%P)if(b&1) re=re*a%P;return re; } inline ll Inv(ll a){return Pow(a,P-2);} void solve(){int m=sqrt(n),ans=0;for(int i=1;i<=m;i++) if(n%i==0){if(i!=1) mod(ans+= f(i)*phi(n/i)%P);if(i*i!=n) mod(ans+= f(n/i)*phi(i)%P);}printf("%lld\n",ans*Inv(n)%P*(k+1)%P); } int main(){freopen("in","r",stdin);sieve(32000);while(scanf("%d%lld",&n,&k)!=EOF){k--;F[1]=k;F[2]=k*(k-1)%P;F[3]=k*(k-1)%P*(k-2)%P;a[0][0]=k-2; a[0][1]=k-1;a[1][0]=1; a[1][1]=0;b[0][0]=F[3];b[0][1]=0;b[1][0]=F[2];b[1][1]=0;solve();} }

?

總結

以上是生活随笔為你收集整理的HDU 2865 Birthday Toy [Polya 矩阵乘法]的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。