JZOJ 5746 和
Description
給定
m
和k
,共T
次詢問,每次詢問一個n
,輸出\sum_{i=1}^ni^k\ mod\ m
資料保證
m
的最大值質因子不超過3*10^5
。
Data Constraints
2\leq n,m,k\leq 10^{18}\ \\ 1\leq T\leq 3*10^3
Solution
首先這題用到了中國剩餘定理,將
m
分解質因數,分解成m=\Pi_{i=1}^v p_i^{a_i}
的形式。 那對於某一詢問,我們只需求出對於每個
i\in [1,v]
,求出\sum_{j=1}^nj^k\ mod\ p_i^{a_i}
,最後用中國剩餘定理組合起來即可。
現在考慮怎麼求
\sum_{j=1}^nj^k\ mod\ p_i^{a_i}
,可以觀察到{a_i}
不會超過59
我們可以將每一個數拆成xp_i+y
的形式,於是我們有 \sum_{j=1}^nj^k\ mod\ p_i^{a_i}=\sum_x\sum_{0\leq y<p_i}[x*p_i+y\leq n](xp_i+y)^k\ mod\ p_i^{a_i}
為了方便,我們將答案寫成
\sum_{j=1}^n(x_jp_i+y_j)^k\ mod\ p_i^{a_i}
我們用二次項定理將
k
次方展開,得 \sum_{j=1}^n\sum_{v=0}^k C_{k}^v(x_jp_i)^vy_j^{k-v}\ mod\ p_i^{a_i}
可以看到,當
v\geq a_i
時,值在模意義下就變成0
了,因此我們又能把式子寫成 \sum_{j=1}^n\sum_{v=0}^{min(a_i,k)} C_{k}^v(x_jp_i)^vy_j^{k-v}\ mod\ p_i^{a_i}
對於每個可能的
v
的取值分開求解,同時預處理出字首和陣列H
, H_{i,u,v}=\sum_{j=1}^u j^{k-v}\ mod\ p_i^{a_i}(u\leq p_i)
這樣我們就能繼續化簡式子,得
\sum_{v=0}^{min(a_i,k)}C_{k}^v[({\lfloor\frac{n}{p_i}\rfloor}p_i)^vH_{i,(n-1)\ mod\ p_i+1,v}+H_{i,\ p_i,v}p_i^v\sum_{j=0}^{\lfloor\frac{n}{p_i}\rfloor-1}j^v]
上式中
C_{k}^v \ mod \ p_i^{a_i}
可以通過預處理出F_v=C_{k}^v \ mod\ m
,再用F_v \ mod \ p_i^{a_i}
得到。
至於
\sum_{j=0}^{\lfloor\frac{n}{p_i}\rfloor-1}j^v
,考慮v
並不會超過59
,所以可以用第二類斯特林數在O(v^2)
的時間複雜度內求解自然數冪和。
乘法要用快速乘。
時間複雜度我沒去算(本蒟蒻太懶了),反正是
O(
能過)
。
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#pragma GCC optimize(3)
#define fo(i,j,l) for(int i=j;i<=l;++i)
#define fd(i,j,l) for(int i=j;i>=l;--i)
using namespace std;
typedef long long ll;
const ll N=12e6,K=1e3,sj=1e7,NN=1000,P=12e2,W=3e5;
ll x[N],oo,ss[NN],gg[NN];
int t,gs[NN];
ll n,m,k;
ll kt[120][305000];
int be[K],en[K];
ll S[P][P],c[P];
ll jj[P];
inline ll mod(ll x,ll y,ll m)
{
ll tmp=(ll)((long double)x*y/m+1e-8)*m;
return (x*y-tmp+m)%m;
}
inline int min(int a,ll b)
{return a<b?a:b;}
inline ll mmo(ll p,ll mo)
{return (p>=mo)?p-mo:p;}
inline ll mmo_m(ll p)
{return (p>=0)?p:(p+m);}
inline ll ksm(ll o,ll t,ll m)
{
ll y=1; o%=m;
for(;t;t>>=1,o=mod(o,o,m))
if(t&1)y=mod(y,o,m);
return y;
}
inline ll ksm_mod(ll o,ll t,ll mo)
{
ll y=1;
for(;t;t>>=1,o=o*o%mo)
if(t&1)y=y*o%mo;
return y;
}
inline ll iabs(ll o)
{return (o>0)?o:(-o);}
inline ll gcd(ll a,ll b)
{return (b==0)?a:gcd(b,a%b);}
inline void prepare()
{
S[1][1]=1; S[1][0]=0;
fo(i,2,K){
S[i][1]=1; S[i][0]=0;
fo(l,2,i)S[i][l]=mmo(S[i-1][l-1]+mod(S[i-1][l],l,m),m);
}
}
inline ll js(ll p,int k,ll m)
{
if(k==0)return (p+1)%m;
ll ans=0;
fo(i,1,k){
ll lj=1;
fo(l,-1,i-1)if((p-l)%(i+1)==0)lj=mod(lj,(p-l)/(i+1),m);
else lj=mod(lj,(p-l),m);
ans=mmo(ans+mod(S[k][i],lj,m),m);
}
return ans;
}
inline ll C(ll a,ll b,ll mo)
{
fo(i,1,b)jj[i]=a-i+1;
fo(i,2,b){
ll dq=i;
fo(i,1,b)if(gcd(jj[i],dq)!=1){
ll up=gcd(jj[i],dq);
dq/=up;
jj[i]/=up;
if(dq==1)break;
}
}
ll op=1;
fo(i,1,b)op=mod(op,jj[i],mo);
return op;
}
inline ll countt(ll x,ll len,int gg,int bh)
{
ll num=(x/len)%len;
ll mo=1,op=0;
fo(i,1,gg)mo=mo*len;
ll kk=(x/len); ll w=1;
fo(i,0,min(gg,k))
{
ll lj=mod(kt[be[bh]+i][x%len],w,mo);
lj=mod(lj,c[i]%mo,mo);
op=mmo(op+lj,mo);
w=mod(w,len,mo);
w=mod(w,kk,mo);
}
w=1;
if(kk)
fo(i,0,min(gg,k)){
ll lj=js(kk-1,i,mo);
lj=mod(lj,w,mo);
lj=mod(lj,kt[be[bh]+i][len],mo);
lj=mod(lj,c[i]%mo,mo);
op=mmo(op+lj,mo);
w=mod(w,len,mo);
}
return op;
}
int main()
{
cin>>m>>k>>t;
ll op=m; prepare();
fo(i,0,60)c[i]=C(k,i,m);
fo(i,2,W)if(op%i==0){
ss[++oo]=i;
while(op%i==0)++gs[oo],op/=i;
}
sort(ss+1,ss+oo+1); int ok=1;
fo(i,1,oo){
ll mo=1;
be[i]=en[i-1]+1; en[i]=be[i]+gs[i];
fo(l,1,gs[i])mo=mo*ss[i];
fo(j,0,min(gs[i],k))
fo(l,1,ss[i])
kt[j+be[i]][l]=mmo(kt[j+be[i]][l-1]+ksm(l,k-j,mo),mo);
}
fo(i,1,t){
scanf("%lld",&n);
ll ans=0;
fo(i,1,oo){
ll p=countt(n,ss[i],gs[i],i);
ll p2=m,mo=1;
fo(j,1,gs[i])mo=mo*ss[i],p2=p2/ss[i];
ll p1=ksm(p2%mo,(mo/ss[i])*(ss[i]-1)-1,mo);
p=mod(p,p1,m); p=mod(p,p2,m);
ans=mmo(ans+p,m);
}
printf("%lld\n",ans);
}
}
相關文章
- jzoj8132 扔骰子
- JZOJ5787 軌道
- JZOJ 6664. 【2020.05.28省選模擬】最最佳化
- jzoj 6797. 【2014廣州市選day2】hanoi
- Jzoj5459【NOIP2017提高A組衝刺11.7】密室
- 路徑中./和../和/
- ../和./和/的區別
- not in 和 not exists 比較和用法
- xftp和xshell,xftp和xshell的下載和安裝FTP
- #和&
- !=和<>
- 字首和與二維字首和
- @NotEmpty和@NotBlank和@NotNull小結Null
- ABAP和Java的destination和JNDIJava
- ♻️同步和非同步;並行和併發;阻塞和非阻塞非同步並行
- XML基本操作-建立(DOM和LOINQ)和LINQ查詢和儲存XML
- ThymeleafViewResolver和SpringTemplateEngine和SpringResourceTemplateResolver的關係ViewSpring
- javafx 和swing_整合JavaFX和SwingJava
- 檔案路徑問題( ./ 和 ../ 和 @/ )
- 尤拉計劃739:和的和
- workman 和swoole 區別 和異同
- 寬鬆相等和嚴格相等(==和===)
- 淺談mouseenter和mouseover,mouseout和mouseleave
- csv和excel讀取和下載Excel
- Cookie 和 Session 關係和區別CookieSession
- 堆和棧的概念和區別
- 【-Flutter/Dart 語法補遺-】 sync* 和 async* 、yield 和yield* 、async 和 awaitFlutterDartAI
- 字首和
- equals 和 ==
- if if和if else if
- ul和
- RestController和Controller的區別和異同RESTController
- Instruction和Question的區別和聯絡Struct
- (Day4)字首和&二維字首和
- vue和react的相同點和不同點VueReact
- pyinstaller和wordcloud和jieba的使用案列CloudJieba
- DOORS和Reqtify—需求管理和需求追溯工具QT
- MySQL 裡的 find_in_set () 和 in () 和 likeMySql