zoukankan      html  css  js  c++  java
  • 2017多校第一套&&hdu6038 思维 数学

    链接  http://acm.hdu.edu.cn/showproblem.php?pid=6038

    题意: 
    给你一个a序列,代表0到n-1的排列;一个b序列代表0到m-1的排列。问你可以找出多少种函数关系f,f的定义域内的i都满足f(i)=b[f(a[i])]; 
    分析:这个主要是找循环节 循环节导致函数有多种情况 找到每段循环节的 取值 种数 相乘起来就是答案
    比如说:如果 a 序列是 2 0 1 那么我们可以发现

    f[0] = b[f(a[0])]     f[0]  = b[f(2)] 
    f[1] = b[f(a[1])]     f[1]  = b[f(0)] 
    f[2] = b[f(a[2])]     f[2]  = b[f(1)]

    对于这组数来说,假如我们先指定了f(0)对应的在b中的值,那么根据第2个式子,就可以得出f(1),根据f(1)就又可以得出f(2),最后根据f(2)就可以检验f(0)的值是否正确。

    仔细观察左边的柿子 (定义域)i与a[ i ] 是循环的 如果想使上述成立,必须右边的柿子(值域)i与b[ i ] 也存在其约数长度的循环节。 

    如果不是约数长度的循环节会使上述假设矛盾    自己写一下就知道了 只有被整出才会成立。

    每个定义域的循环节都可以与每个值域的循环节匹配(满足红字匹配成功)

    那么就是找两个序列的不相交的循环节,对于定义域里面的每一个循环节都找出来有多少种情况。每一个循环节的情况数为它所能匹配的值域循环节的长度 和。每个循环节的情况数起来就是答案了

    样例一  (1+1)*(1+1)=4; a两个环(长度 2 1)           b两个个环(长度 1 1)       2与1 1匹配   1与1 1 匹配

    样例二  (1+3)=4;           a一个环(长度 3)                b两个环(长度 1 3)         3与1 3匹配 

    注   对于一个a循环节  若b循环节中没有能与之匹配的   答案为零   想想为什么  不用特判累积过程中可以处理掉

    AC代码

     1 #include <stdio.h>
     2 #include <math.h>
     3 #include <string.h>
     4 #include <stdlib.h>
     5 #include <iostream>
     6 #include <sstream>
     7 #include <algorithm>
     8 #include <string>
     9 #include <queue>
    10 #include <vector>
    11 using namespace std;
    12 const int maxn= 1e5+10;
    13 const int mod= 1e9+7;
    14 const int inf = 0x3f3f3f3f;
    15 typedef long long ll;
    16 int n,m;
    17 int a[maxn],b[maxn];
    18 int vis[maxn],loop_a[maxn],loop_b[maxn];   //loop存循环节长度
    19 int main()
    20 {
    21     int kase=0;
    22     while(scanf("%d %d",&n,&m)!=EOF)
    23     {
    24         for(int i=0; i<n; i++)
    25             scanf("%d",&a[i]);
    26         for(int i=0; i<m; i++)
    27             scanf("%d",&b[i]);
    28         memset(vis, 0, sizeof(vis));      //标记是否访问过 找不相交的循环节
    29         memset(loop_b, 0, sizeof(loop_b));
    30         memset(loop_a, 0, sizeof(loop_a));
    31         int cnt1=0,cnt2=0;                   //cnt记录循环节个数
    32         for(int i = 0; i < n; i++)
    33         {
    34             if(!vis[i])                      //过程自己模拟一下就明了了
    35             {
    36                 int x = a[i];
    37                 int len = 0;
    38                 while(!vis[x])
    39                 {
    40                     len++;
    41                     vis[x] = 1;
    42                     x = a[x];
    43                 }
    44                 if(len!=0)
    45                     loop_a[cnt1++]=len;         //保存循环节
    46             }
    47         }
    48         memset(vis, 0, sizeof vis);
    49         for(int i = 0; i < m; i++)      //b同理
    50         {
    51             if(!vis[i])
    52             {
    53                 int x = b[i];
    54                 int len = 0;
    55                 while(!vis[x])
    56                 {
    57                     len++;
    58                     vis[x] = 1;
    59                     x = b[x];
    60                 }
    61                 if(len!=0)
    62                     loop_b[cnt2++]=len;
    63             }
    64         }
    65         ll ans=1;
    66         for(int i=0; i<cnt1; i++)            //枚举a与b的循环节 试了不会超时 还有更快一些的做法
    67         {
    68             ll sum=0;                //记录每个循环节的情况数
    69             for(int j=0; j<cnt2; j++)    
    70             {
    71                 if(loop_a[i]%loop_b[j]==0)    //只有是约数才能匹配
    72                 {
    73                     sum=(sum+loop_b[j])%mod;     //加进去 取模
    74                 }
    75             }
    76             ans=(ans*sum)%mod;                //乘到答案里面
    77         }
    78         printf("Case #%d: %lld
    ",++kase,ans);
    79     }
    80     return 0;
    81 }

    作者水平有限 欢迎大佬纠错!

    多校真jb难啊~~~~~QAQ

    太菜了

  • 相关阅读:
    精选的一些《编程之美》相关资料
    使用SftpDrive+SourceInsight阅读开源代码
    malloc()参数为0的情况
    《编程之美》4.5磁带文件存放优化:最优解是怎样炼成的
    从《编程之美》买票找零问题说起,娓娓道来卡特兰数——兼爬坑指南
    《编程之美》3.6判断链表是否相交之扩展:链表找环方法证明
    解答《编程之美》1.18问题1:给所有未标识方块标注有地雷概率
    C语言中 Float 数据结构的存储计算
    C#之内存分配
    unity----------------3D模型讲解
  • 原文地址:https://www.cnblogs.com/stranger-/p/7775410.html
Copyright © 2011-2022 走看看