生活随笔
收集整理的這篇文章主要介紹了
单位根反演题单
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
單位根反演題單
LOJ#6485. LJJ 學二項式定理
單位根反演。
bzoj 3328 PYXFIB
單位根反演+矩陣乘法。
POJChallengeRound2 Guideposts
求圖上路徑長度為k的倍數的方案數。
單位根反演+矩陣乘法。
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se secondusing namespace std
;template<typename T
>inline bool upmin(T
&x
,T y
) { return y
<x
?x
=y
,1:0; }
template<typename T
>inline bool upmax(T
&x
,T y
) { return x
<y
?x
=y
,1:0; }typedef long long ll
;
typedef unsigned long long ull
;
typedef long double lod
;
typedef pair
<int,int> PR
;
typedef vector
<int> VI
;const lod eps
=1e-11;
const lod pi
=acos(-1);
const int oo
=1<<30;
const ll loo
=1ll<<62;
const int MAXN
=600005;
const int INF
=0x3f3f3f3f;
inline int read()
{int f
=1,x
=0; char c
=getchar();while (c
<'0'||c
>'9') { if (c
=='-') f
=-1; c
=getchar(); }while (c
>='0'&&c
<='9') { x
=(x
<<3)+(x
<<1)+(c
^48); c
=getchar(); }return x
*f
;
}
ll n
;
int m
,k
,mods
;
int upd(int x
,int y
){ return x
+y
>=mods
?x
+y
-mods
:x
+y
; }
int quick_pow(int x
,int y
)
{int ret
=1;for (;y
;y
>>=1){if (y
&1) ret
=1ll*ret
*x
%mods
;x
=1ll*x
*x
%mods
;}return ret
;
}
int flag
[MAXN
],prime
[MAXN
],a
[MAXN
],pnum
=0,cnt
=0;
void Prime_Init(int n
)
{flag
[1]=1;for (int i
=2;i
<=n
;i
++){if (!flag
[i
]) prime
[++cnt
]=i
;for (int j
=1;prime
[j
]*i
<=n
&&j
<=cnt
;j
++) {flag
[prime
[j
]*i
]=1;if (!(i
%prime
[j
])) break;}}
}
void findp(int x
)
{x
--,pnum
=0;for (int i
=1;prime
[i
]*prime
[i
]<=x
;i
++)if (!(x
%prime
[i
])){a
[++pnum
]=prime
[i
];while (!(x
%prime
[i
])) x
/=prime
[i
];}
}
int getwn(int x
)
{findp(x
);for (int i
=2;;i
++){bool flag
=1;for (int j
=1;j
<=pnum
;j
++){int t
=(x
-1)/a
[j
];if (quick_pow(i
,t
)==1) { flag
=0; break; } }if (flag
) return i
;}
}struct Matrix
{int n
,A
[5][5];void init(){ for (int i
=0;i
<n
;i
++) A
[i
][i
]=1; }Matrix(int n1
=0){n
=n1
;memset(A
,0,sizeof A
);}Matrix
operator * (const Matrix
&b
){Matrix
Ans(n
);for (int i
=0;i
<n
;i
++)for (int j
=0;j
<n
;j
++)for (int k
=0;k
<n
;k
++) Ans
.A
[i
][j
]=upd(Ans
.A
[i
][j
],1ll*A
[i
][k
]*b
.A
[k
][j
]%mods
);return Ans
;}Matrix
operator + (const Matrix
&b
){Matrix
Ans(n
);for (int i
=0;i
<n
;i
++)for (int j
=0;j
<n
;j
++) Ans
.A
[i
][j
]=upd(Ans
.A
[i
][j
],(A
[i
][j
]+b
.A
[i
][j
])%mods
);return Ans
;}Matrix
operator ^ (const int &b
){Matrix
ret(n
),x
=*this;ret
.init();for (ll y
=b
;y
;y
>>=1){if (y
&1) ret
=ret
*x
;x
=x
*x
;}return ret
;}void print(){for (int i
=0;i
<n
;i
++){for (int j
=0;j
<n
;j
++) cout
<<setw(4)<<A
[i
][j
];cout
<<endl
;}cout
<<endl
;}
};
void build(Matrix
&f
,Matrix
&G
,int w
)
{for (int i
=0;i
<m
;i
++)for (int j
=0;j
<m
;j
++) f
.A
[i
][j
]=1ll*G
.A
[i
][j
]*w
%mods
;for (int i
=0;i
<m
;i
++) f
.A
[i
][i
]=upd(f
.A
[i
][i
],1);
}
int main()
{Prime_Init(100000);while (scanf("%d%lld",&m
,&n
)!=EOF){k
=read(),mods
=read();int l
=read(),s
=read()-1,t
=read()-1;Matrix
f(m
),Ans(m
),G(m
);for (int i
=1;i
<=l
;i
++){int u
=read()-1,v
=read()-1;G
.A
[u
][v
]++;}int wn
=getwn(mods
),ans
=0;wn
=quick_pow(wn
,(mods
-1)/k
);
for (int i
=0,w
=1;i
<k
;i
++,w
=1ll*w
*wn
%mods
){build(f
,G
,w
);
Ans
=f
^n
;
ans
=upd(ans
,Ans
.A
[s
][t
]);}printf("%d\n",1ll*ans
*quick_pow(k
,mods
-2)%mods
);}return 0;
}
總結
以上是生活随笔為你收集整理的单位根反演题单的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。