$f_i=(f_{i-1}^{b_1}\cdot f_{i-2}^{b_2} \cdot\cdot\cdot f_{i-k}^{b_k})mod \ p\ (i\geq k)$

$f_n$

PS：以前在CF里见到过一个$k=3$的情况，当时再考场上推到第8项发现每一项的指数都可以递推，当时搞不明白为什么，今天想的时候就清楚了。

$\left[ \matrix{ dp_i\ dp_{i+1}\ dp_{i+2}...dp_{i+k-1} } \right] \cdot \left[ \matrix{ 0\ 0\ 0\ ...\ 0\ b_k\quad\\ 1\ 0\ 0\ ...\ 0\ b_{k-1}\\ 0\ 1\ 0\ ...\ 0\ b_{k-2}\\ ...\\ 0\ 0\ 0\ ...\ 1\ b_{1} } \right] = \left[ \matrix{ dp_{i+1}\ dp_{i+2}\ dp_{i+3}...dp_{i+k} } \right]$

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

x=0; char c=getchar();
while(c<'0'||'9'<c)c=getchar();
while('0'<=c&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();}
}
typedef long long ll;
const int K=205;
const int M=998244353;
int n,m,a,b[K];
ll ans=1ll;
struct matrix{
int x[K][K],r,c;
void clear(){memset(x,0,sizeof(x));}
matrix operator * (const matrix &_)const{
matrix __; __.clear();
__.r=r; __.c=_.c;
for(int k=1;k<=c;k++)
for(int i=1;i<=r;i++) if(x[i][k])
for(int j=1;j<=_.c;j++) if(_.x[k][j])
__.x[i][j]=(__.x[i][j]+1ll*x[i][k]*_.x[k][j]%(M-1))%(M-1);
return __;
}
}u,v,w;
int qpow(int x,int y){
ll tmp=1,base=x;
while(y){
if(y&1)tmp=(tmp*base)%M;
base=(base*base)%M; y>>=1;
} return tmp;
}
matrix mpow(matrix _,int _b){
matrix res,base=_;
res.clear(); res.c=res.r=m;
for(int i=1;i<=m;i++)res.x[i][i]=1;
while(_b){
if(_b&1)res=res*_;
_=_*_; _b>>=1;
} return res;
}
int main(){
//	freopen("seq.in","r",stdin);
//	freopen("seq.out","w",stdout);
if(n<=m){
printf("%d\n",a);
return 0;
}
for(int i=1;i<=m;i++)v.x[i][m]=b[m-i+1], v.x[i][i-1]=1;
v.c=v.r=m; v=mpow(v,n-m);
for(int i=1;i<=m;i++){
u.clear(); u.x[1][i]=1;
u.c=m; u.r=1; u=u*v;
ans=(ans*qpow(a,u.x[1][m]))%M;
}
printf("%lld\n",ans);
return 0;
}


#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;

x=0; char c=getchar();
while(c<'0'||'9'<c)c=getchar();
while('0'<=c&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();}
}

const int N=200050;

int n,m,t[N],ans;
struct seg{
int l,r;
bool operator >(const seg _)const{return r<_.r;}
bool operator <(const seg _)const{return r>_.r;}
}s[N];
priority_queue<seg>q;
bool cmp(seg _,seg __){return _.l<__.l;}
int main(){
freopen("dream.in","r",stdin);
freopen("dream.out","w",stdout);
sort(s+1,s+n+1,cmp); sort(t+1,t+m+1); int p=0;
for(int i=1;i<=m;i++){
if(p<n) while(p<n&&s[p+1].l<=t[i]) q.push(s[++p]);
if(!q.empty()) while(!q.empty()&&q.top().r<t[i]) q.pop();
if(!q.empty()) if(q.top().l<=t[i]&&t[i]<=q.top().r) ++ans, q.pop();
}
printf("%d\n",ans);
return 0;
}


$x$$y$间不存在父子关系：

$x$$y$间存在父子关系：

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;

x=0; char c=getchar();
while(c<'0'||'9'<c)c=getchar();
while('0'<=c&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();}
}
typedef long long ll;
typedef pair<int,int> pr;
const int N=100050;

int n,m;
vector<int>e[N];
int dep[N],siz[N],fa[N],son[N];
int top[N],dfn[N],tail[N],cnt;
ll ans;
vector<pr> in[N],del[N];
struct segt{
int s[N<<2],rm[N<<2];
void pushup(int l,int r,int p){
if(rm[p]) s[p]=r-l+1;
else if(l==r) s[p]=0;
else s[p]=s[p<<1]+s[p<<1|1];
}
void add(int L,int R,int c,int l,int r,int p){
if(L<=l&&r<=R){ rm[p]+=c; pushup(l,r,p); return ;}
int mid=(l+r)>>1;
pushup(l,r,p);
}
}t;

void dfs1(int x){
siz[x]=1; son[x]=0;
for(int i=e[x].size()-1,y;~i;i--){
y=e[x][i]; if(y==fa[x]) continue;
dep[y]=dep[x]+1; fa[y]=x;
dfs1(y); siz[x]+=siz[y];
if(siz[y]>siz[son[x]]) son[x]=y;
}
}
void dfs2(int x,int tp){
top[x]=tp; dfn[x]=++cnt;
if(son[x])dfs2(son[x],tp);
for(int i=e[x].size()-1,y;~i;i--){
y=e[x][i]; if(y==son[x]||y==fa[x]) continue;
dfs2(y,y);
}
}
int lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) y=fa[top[y]];
else x=fa[top[x]];
}
return dep[x]<dep[y]?x:y;
}
int find(int x,int y){
while(top[x]!=top[y]){y=top[y]; if(fa[y]==x) return y; y=fa[y];}
return son[x];
}
void insert(int x1,int x2,int y1,int y2){
in[y1].push_back(pr(x1,x2));
del[y2].push_back(pr(x1,x2));
}
int main(){
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
for(int i=1;i<n;i++){
e[x].push_back(y);
e[y].push_back(x);
}
fa[6]=6; dep[6]=1; dfs1(6); dfs2(6,6); cnt=0;
for(int i=1;i<=n;i++) tail[i]=dfn[i]+siz[i]-1;
for(int i=1,sx;i<=m;i++){
if(dfn[x]>dfn[y]) swap(x,y);
if(lca(x,y)==x){
sx=find(x,y);
if(dfn[y]>1) insert(dfn[y],tail[y],1,dfn[sx]-1);
if(tail[y]<n) insert(tail[sx]+1,n,dfn[y],tail[y]);
}
else insert(dfn[y],tail[y],dfn[x],tail[x]);
}
pr a;
for(int i=1;i<=n;i++){