题解:CF1574F Occurrences
Tokisaki__kurumi · · 题解
CF1574F
思路:我们发现对于一个
code
int n,m,k;
int pre[N],to[N];
int f[N],g[N],w[N];
int fa[N],sz[N];
int tag[N];
int a[N];
inline int find(int x){return fa[x]==x?fa[x]:fa[x]=find(fa[x]);}
inline void merge(int x,int y){
x=find(x),y=find(y);
if(x==y){tag[x]=1;return;}
fa[x]=y;
tag[y]|=tag[x];
sz[y]+=sz[x];
}
inline void solve(){
read(n,m,k);
for(int i=1;i<=k;++i) fa[i]=i,sz[i]=1;
for(int i=1;i<=n;++i){
int c;
read(c);
for(int j=1;j<=c;++j){
read(a[j]);
if(j==1) continue;
if((pre[a[j]]&&pre[a[j]]!=a[j-1])||(to[a[j-1]]&&to[a[j-1]]!=a[j])) merge(a[j-1],a[j]),tag[find(a[j])]|=1;
else if(!to[a[j-1]]){
to[a[j-1]]=a[j];
pre[a[j]]=a[j-1];
merge(a[j-1],a[j]);
}
}
}
for(int i=1;i<=k;++i){
if(find(i)!=i||tag[i]) continue;
g[sz[i]]++;
}
int cnt=0;
for(int i=1;i<=m;++i){
if(g[i]) w[++cnt]=i;
}
f[0]=1;
for(int i=0;i<=m;++i){
for(int j=1;j<=cnt&&w[j]+i<=m;++j){
f[i+w[j]]=(f[i+w[j]]+1ll*f[i]*g[w[j]]%mod)%mod;
}
}
write(f[m]);
}