zoukankan      html  css  js  c++  java
  • 2017年7月25日多校一Function

       Function这道题我当时一直很迷,到底怎么来的啊,为什么会这样啊??
       然后看了题解才知道,原来是找循环啊。
       已知f(i)=b[f(a(i)],则  
       f(0) = b[f(a[0])] = b[f(2)] 
       f[1] = b[f(a[1])] = b[f(0)] 
       f[2] = b[f(a[2])] = b[f(1)]
       其实这道题可以转化为求环的问题,有多少种方式可以构成题目要求的环,即b的环可以有多少种方式画成a的环。
       第一个样例我们可以知道 a0->a1->a0,  a2->a2,  b0->b0, b1->b1。
       则和a同构的环有b0->b0->b0, b1->b1->b1, b0->b0, b1->b1四个
       第二个样例我们可以知道a0->a2->a1->a0  b0->b0  b1->b2->b3->b1
       则和a同构的环有b1->b2->b3->b1   b2->b3->b1->b2  b3->b1->b2->b3   b0->b0->b0->b0四个
       然后找出所有环的长度,是a环的因子的就加起来,最后将所有的乘起来(为什么是乘起来??因为组合数学啊(●'◡'●))
    ll ans=1;
       for (int i=0; i<va.size(); i++) {
           ll num=0;
           for (int j=0; j<vb.size(); j++) {
              if (va[i]%vb[j]==0) num+=vb[j];
            }
           ans = ans*num%mod;
       }
     代码:
    /*  gyt
           Live up to every day            */
    #include<cstdio>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<cstring>
    #include<queue>
    #include<set>
    #include<string>
    #include<map>
    #include <time.h>
    #define PI acos(-1)
    using namespace std;
    typedef long long ll;
    typedef double db;
    const int maxn = 1e5+10;
    const ll maxm = 1e7;
    const ll mod = 1e9+7;
    const int INF = 1<<30;
    const db eps = 1e-8;
    int a[maxn], b[maxn];
    bool visa[maxn], visb[maxn];
    vector<ll>va, vb;
    int ca=1;
    int flag;
    void init() {
        memset(a, 0, sizeof(a));
        memset(b, 0, sizeof(b));
        memset(visa, 0, sizeof(visa));
        memset(visb, 0, sizeof(visb));
        va.clear();
        vb.clear();
    }
    void solve() {
        int n, m;
        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++) {
                if (visa[i])  continue;
                int x=i;  int sum=0;
                while(x!=a[x]) {
                    if (visa[x])  break;
                    visa[x]=1;
                    sum++;
                   // cout<<x<<" "<<a[x]<<endl;
                    x=a[x];
                }
                //cout<<x<<endl;
                if (x==i) {
                   // cout<<"sum:"<<sum<<endl;
                    if (sum==0)  va.push_back(1);
                    else  va.push_back(sum);
                } else {
                    x=i;  int num=0;
                    while(x!=a[x]) {
                        if (num>=sum)  break;
                        visa[x]=0;
                        num++;
                        x=a[x];
                    }
                    visa[i]=1;  va.push_back(1);
                }
            }
            for (int i=0; i<m; i++) {
                if (visb[i])  continue;
                int x=i;  int sum=0;
                while(x!=b[x]) {
                    if (visb[x])  break;
                    visb[x]=1;
                    sum++;
                    x=b[x];
                }
                if (x==i) {
                    if (sum==0)  vb.push_back(1);
                    else  vb.push_back(sum);
                } else {
                    x=i;  int num=0;
                    while(x!=a[x]) {
                        if (num>=sum)  break;
                        visb[x]=0;
                        num++;
                        x=b[x];
                    }
                    visb[i]=1;  vb.push_back(1);
                }
            }
            ll ans=1;
            for (int i=0; i<va.size(); i++) {
                ll num=0;
                for (int j=0; j<vb.size(); j++) {
                    if (va[i]%vb[j]==0) num+=vb[j];
                }
                ans = ans*num%mod;
            }
            printf("Case #%d: %lld
    ", ca++, ans);
        }
    }
    int main() {
        //freopen("in.txt","r",stdin);
      //  freopen("kingdom.in","r",stdin);
        //freopen("kingdom.out","w",stdout);
        int t=1;
       // scanf("%d", &t);
        while(t--)  solve();
    }
    
    
    
     
  • 相关阅读:
    UVA 10462 Is There A Second Way Left?(次小生成树&Prim&Kruskal)题解
    POJ 1679 The Unique MST (次小生成树)题解
    POJ 2373 Dividing the Path (单调队列优化DP)题解
    BZOJ 2709 迷宫花园
    BZOJ 1270 雷涛的小猫
    BZOJ 2834 回家的路
    BZOJ 2506 calc
    BZOJ 3124 直径
    BZOJ 4416 阶乘字符串
    BZOJ 3930 选数
  • 原文地址:https://www.cnblogs.com/gggyt/p/7241328.html
Copyright © 2011-2022 走看看