cf1327D,E——组合数学

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<<'\n';
    }
} 

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]<<" ";
}

 

posted on 2020-03-24 14:58  zsben  阅读(223)  评论(0编辑  收藏  举报

导航