zoukankan      html  css  js  c++  java
  • hdu 6038

    题意:给出a,b序列,求多少种f序列,f序列是f(i)=b(f(ai)).

    思路:从例子出发3  4  

            2  0  1

            0  2  3 1

       可以知道a序列有个长度为3的循环节,即a[0]=2,a[1]=0,a[2]=1, b序列有长度为1和3的循环节  长度为1的:a[0]=0;

                                                      长度为3的:a[1]=2,a[2]=3,a[3]=1;

       那么a长度3的循环节自然可以匹配长度为1的和长度为3的循环节,但如果我b改为0 2 1 3,它的循环节就变成长度为1和2的,那么就只能匹配长度为1的循环节,可以自己手动模拟下,

     1 #include<bits/stdc++.h>
     2 using namespace  std;
     3 typedef long long ll;
     4 const int N=1e5+10;
     5 const ll mod=1e9+7;
     6 
     7 int a[N],b[N];
     8 int aa[N],bb[N];
     9 int vis[N];
    10 
    11 int main(){
    12     int k=1;
    13     int n,m;
    14     while(scanf("%d%d",&n,&m)!=EOF){
    15         for(int i=0;i<n;i++) scanf("%d",&a[i]);
    16         for(int i=0;i<m;i++) scanf("%d",&b[i]);
    17         memset(vis,0,sizeof(vis));
    18         memset(aa,0,sizeof(aa));
    19         memset(bb,0,sizeof(bb));
    20         for(int i=0;i<n;i++){
    21             int cnt=0;
    22             int x=i;
    23             while(!vis[x]){
    24                 cnt++;
    25                 vis[x]=1;
    26                 x=a[x];
    27             }
    28             //cout<<cnt<<endl;
    29             aa[cnt]++;//a该循环节的个数++
    30         }
    31         memset(vis,0,sizeof(vis));
    32         for(int i=0;i<m;i++){
    33             int cnt=0;
    34             int x=i;
    35             while(!vis[x]){
    36                 cnt++;
    37                 vis[x]=1;
    38                 x=b[x];
    39             }
    40            //cout<<cnt<<endl;
    41             bb[cnt]++;//b该循环节的个数++
    42         }
    43         ll sum=1;
    44         for(int i=1;i<=n;i++){
    45             if(aa[i]){
    46                // cout<<i<<endl;
    47                 ll ans=0;
    48                 for(int j=1;j*j<=i;j++){//在b的循环节中找到和a匹配的,即a的因子
    49                     if(i%j==0){
    50                         ans=(ans+bb[j]*j)%mod;//循环节的个数*循环节的长度,代表循环节里的这些数都可以形成f
    51                        // cout<<bb[j]<<" ";
    52                         if(j*j!=i){
    53                             ans=(ans+bb[i/j]*(i/j))%mod;
    54                         }
    55                     }
    56                 }
    57               //  cout<<ans<<endl;
    58                 while(aa[i]--){//对于a每个循环节都有ans个,所以*
    59                     sum=sum*(ans)%mod;
    60                 }
    61             }
    62         }
    63         printf("Case #%d: ",k++);
    64         printf("%I64d
    ",sum);
    65     }
    66     return 0;
    67 }

     

  • 相关阅读:
    LeetCode 382. Linked List Random Node
    LeetCode 398. Random Pick Index
    LeetCode 1002. Find Common Characters
    LeetCode 498. Diagonal Traverse
    LeetCode 825. Friends Of Appropriate Ages
    LeetCode 824. Goat Latin
    LeetCode 896. Monotonic Array
    LeetCode 987. Vertical Order Traversal of a Binary Tree
    LeetCode 689. Maximum Sum of 3 Non-Overlapping Subarrays
    LeetCode 636. Exclusive Time of Functions
  • 原文地址:https://www.cnblogs.com/hhxj/p/7237973.html
Copyright © 2011-2022 走看看