d:把排列当成环拉出来,老套路了
/* 把每个环拉出来,然后枚举长度的因子,判是否可行 */ #include<bits/stdc++.h> using namespace std; #define N 200005 int vis[N],n,p[N],c[N],ans; vector<int>v; void dfs(int u){ if(vis[u])return; vis[u]=1; v.push_back(u); dfs(p[u]); } void solve(){ for(int len=1;len<=v.size();len++)if(v.size()%len==0){ for(int j=0;j<len;j++){ int flag=0; for(int k=j;k<v.size();k+=len) if(c[v[k]]!=c[v[(k+len)%v.size()]])flag=1; if(flag==0){ ans=min(ans,len); return; } } } } int main(){ int t;cin>>t; while(t--){ for(int i=1;i<=n;i++)vis[i]=0; ans=0x3f3f3f3f; cin>>n; for(int i=1;i<=n;i++)cin>>p[i]; for(int i=1;i<=n;i++)cin>>c[i]; for(int i=1;i<=n;i++)if(!vis[i]){ v.clear();dfs(i); solve(); } cout<<ans<<' '; } }
E:组合数学计数,老是会想歪
#include<bits/stdc++.h> using namespace std; #define mod 998244353 #define ll long long #define N 200005 ll Pow(ll a,ll b){ ll res=1; while(b){ if(b%2)res=res*a%mod; b>>=1;a=a*a%mod; } return res; } ll n,dp[N]; int main(){ cin>>n; dp[1]=10;dp[2]=180; for(int i=3;i<=n;i++){ dp[i]=Pow(10,i-1)*9%mod;//第i位的贡献 dp[i]=(dp[i]+dp[i-1]*10%mod)%mod;//所有1的贡献*10 dp[i]=(dp[i]-10*9*Pow(10,i-3)%mod+mod)%mod; //减掉第i位和第i-1位相等的情况 } for(int i=1;i<=n;i++)cout<<dp[n-i+1]<<" "; }