zoukankan      html  css  js  c++  java
  • 2017 多校训练 1006 Function

      

    Function

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 273    Accepted Submission(s): 99


    Problem Description
    You are given a permutation a from 0 to n1 and a permutation b from 0 to m1.

    Define that the domain of function f is the set of integers from 0 to n1, and the range of it is the set of integers from 0 to m1.

    Please calculate the quantity of different functions f satisfying that f(i)=bf(ai) for each i from 0 to n1.

    Two functions are different if and only if there exists at least one integer from 0 to n1 mapped into different integers in these two functions.

    The answer may be too large, so please output it in modulo 109+7.
     
    Input
    The input contains multiple test cases.

    For each case:

    The first line contains two numbers n, m(1n100000,1m100000)

    The second line contains n numbers, ranged from 0 to n1, the i-th number of which represents ai1.

    The third line contains m numbers, ranged from 0 to m1, the i-th number of which represents bi1.

    It is guaranteed that n106, m106.
     
    Output
    For each test case, output "Case #xy" in one line (without quotes), where x indicates the case number starting from 1 and y denotes the answer of corresponding case.
     
    Sample Input
    3 2 1 0 2 0 1 3 4 2 0 1 0 2 3 1
     
    Sample Output
    Case #1: 4 Case #2: 4
     
    Source
     
    /*
    * @Author: Lyucheng
    * @Date:   2017-07-25 15:25:56
    * @Last Modified by:   Lyucheng
    * @Last Modified time: 2017-07-25 20:42:28
    */
    /*
     题意:给你两个序列,定义一种函数 f(i)=b[f(ai)] ,问你已给出的序列可以构造出的函数的数量
    
     思路:实际上就是从a集合到b集合的映射的组合,a中的一个循环节是一个整体,如果b中循环节的长度和a循环节的长度相同
        或者是因子,那么就可以置换过来,满足这个条件,将结果组合一下就好
    
     感悟:好气啊,想出来,但是没想到因子这个条件... 
    */
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define MAXN 100005
    const long long MOD = 1e9+7;
    #define LL long long
    using namespace std;
    
    int n,m;
    int a[MAXN];
    int b[MAXN];
    bool visa[MAXN];
    bool visb[MAXN];
    vector<int> va;
    vector<int> vb;
    int ca=1;
    
    void init(){
        va.clear();
        vb.clear();
        memset(visa,false,sizeof visa);
        memset(visb,false,sizeof visb);
        memset(a,0,sizeof a);
        memset(b,0,sizeof b);
    }
    
    int main(){
        // freopen("in.txt", "r", stdin);
        // freopen("out.txt", "w", stdout);
        while(scanf("%d%d",&n,&m)!=EOF){
    
            init();
            for(int i=0;i<n;i++){
                scanf("%d",&a[i]);
            }
            for(int i=0;i<m;i++){
                scanf("%d",&b[i]);
            }
    
            for(int i=0;i<n;i++){//求A的循环节
                if(visa[i]==true) continue;
    
                int cur=0;
                int x=a[i];
                while(x!=a[x]){
                    if(visa[x]==true) break;//走到了标记过的点 可能遇到没返回自己的循环了,也可能返回自己了
                    visa[x]=true;
                    cur++;
                    x=a[x];
                }
                if(x==a[i]){
                    if(cur==0)
                        va.push_back(1);
                    else
                        va.push_back(cur);
                }else{
                    va.push_back(1);
                    int cnt=0;
                    while(x!=a[x]){
                        cnt++;
                        if(cnt>=cur) break;
                        visa[x]=false;
                        x=a[x];
                    }
                    visa[a[i]]=true;
                }
            }
    
            for(int i=0;i<m;i++){//求B的循环节
                if(visb[i]==true) continue;
    
                int cur=0;
                int x=b[i];
                while(x!=b[x]){
                    if(visb[x]==true) break;//走到了标记过的点 可能遇到没返回自己的循环了,也可能返回自己了
                    visb[x]=true;
                    cur++;
                    x=b[x];
                }
                if(x==b[i]){
                    if(cur==0)
                        vb.push_back(1);
                    else
                        vb.push_back(cur);
                }else{
                    vb.push_back(1);
                    int cnt=0;
                    while(x!=b[x]){
                        cnt++;
                        if(cnt>=cur) break;
                        visb[x]=false;
                        x=b[x];
                    }
                    visb[b[i]]=true;
                }
            }
    
            LL res=1;
            for(int i=0;i<va.size();i++){
                LL cur=0;
                for(int j=0;j<vb.size();j++){
                    if(va[i]%vb[j]==0){
                        cur+=( (LL)(vb[j]) ) %MOD;
                        cur%=MOD;
                    }
                }
                res=( (res%MOD) * (cur%MOD) )%MOD;
            }
    
            printf("Case #%d: %d
    ",ca++,res);
        }
        return 0;
    }
  • 相关阅读:
    [多线程]使用信号量进行同步
    [多线程]互斥锁与信号量的区别
    [多线程]环形缓冲区以及多线程条件同步
    [多线程]LINUX c多线程编程-线程初始化与建立
    [STL]bitset使用
    [算法]败者树
    【Rollo的Python之路】Python:字符串内置函数
    【Rollo的Python之路】Python:字典的学习笔记
    【Rollo的Python之路】 购物车程序练习
    【Rollo的Python之路】Python 元组的学习
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/7236371.html
Copyright © 2011-2022 走看看